├── .babelrc ├── .flowconfig ├── .gitattributes ├── .gitignore ├── .npmignore ├── .prettierrc ├── .vscode └── settings.json ├── LICENSE.md ├── README.md ├── android ├── README.md ├── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── reactlibrary │ ├── IndySdkModule.java │ └── IndySdkPackage.java ├── ios ├── IndySdk-Bridging-Header.h ├── IndySdk.m ├── IndySdk.swift ├── IndySdk.xcodeproj │ └── project.pbxproj └── IndySdk.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── license-header ├── license-header.config.json ├── package.json ├── rn-indy-sdk.podspec ├── src └── index.js └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-flow"] 3 | } 4 | -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | 3 | [include] 4 | 5 | [libs] 6 | 7 | [lints] 8 | 9 | [options] 10 | 11 | [strict] 12 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # node.js 6 | # 7 | node_modules/ 8 | npm-debug.log 9 | yarn-error.log 10 | 11 | # Xcode 12 | # 13 | build/ 14 | *.pbxuser 15 | !default.pbxuser 16 | *.mode1v3 17 | !default.mode1v3 18 | *.mode2v3 19 | !default.mode2v3 20 | *.perspectivev3 21 | !default.perspectivev3 22 | xcuserdata 23 | *.xccheckout 24 | *.moved-aside 25 | DerivedData 26 | *.hmap 27 | *.ipa 28 | *.xcuserstate 29 | project.xcworkspace 30 | 31 | # Android/IntelliJ 32 | # 33 | build/ 34 | .idea 35 | .gradle 36 | local.properties 37 | *.iml 38 | 39 | # BUCK 40 | buck-out/ 41 | \.buckd/ 42 | *.keystore 43 | 44 | # NPM package 45 | rn-indy-sdk-*.tgz 46 | 47 | # Build output 48 | lib 49 | 50 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | android/.idea 2 | android/build 3 | rn-indy-sdk-1.0.0.tgz 4 | /src/ 5 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 120, 3 | "semi": false, 4 | "singleQuote": true, 5 | "trailingComma": "es5" 6 | } 7 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.validate.enable": false, 3 | "javascript.validate.enable": false 4 | } 5 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React Native Indy SDK 2 | 3 | React Native Indy SDK wrapper. 4 | 5 | ## Installation 6 | 7 | with npm: 8 | `$ npm install rn-indy-sdk --save` 9 | 10 | with Yarn: 11 | `$ yarn add rn-indy-sdk` 12 | 13 | Link (for React Native lower than 0.60) 14 | 15 | `$ react-native link rn-indy-sdk` 16 | 17 | ## Android 18 | 19 | See https://github.com/TimoGlastra/ExampleRnIndySDK for an example android react native project that follows this tutorial. 20 | 21 | ### 1. Set min SDK version 22 | 23 | Make sure there is a min. SDK version setup in `android/build.gradle`: 24 | 25 | ```groovy 26 | buildscript { 27 | ext { 28 | ... 29 | minSdkVersion = 21 30 | ... 31 | } 32 | } 33 | ``` 34 | 35 | ### 2. Add Sovrin Maven repository 36 | 37 | Add Sovrin Maven repository into `android/build.gradle`: 38 | 39 | ```groovy 40 | allprojects { 41 | repositories { 42 | ... 43 | maven { 44 | url 'https://repo.sovrin.org/repository/maven-public' 45 | } 46 | ... 47 | } 48 | } 49 | ``` 50 | 51 | ### 3. Add JNA library dependency 52 | 53 | Add to `android/app/build.gradle`: 54 | 55 | ```groovy 56 | dependencies { 57 | // ... 58 | implementation 'net.java.dev.jna:jna:5.2.0' 59 | 60 | // ... 61 | } 62 | ``` 63 | 64 | ### 4. Add Android libindy binaries 65 | 66 | Download Android libindy binaries and copy them into `android/app/src/main/jniLibs`. 67 | 68 | 1. Create `android/app/src/main/jniLibs` directory in your project 69 | 2. Create subdirectories `arm64-v8a`, `armeabi-v7a`, `x86` and `x86_64` inside `android/app/src/main/jniLibs`. 70 | 3. Download the required libindy binaries for your release-channel and version 71 | - with `stable` channel and version `1.15.0` base url will be https://repo.sovrin.org/android/libindy/stable/1.15.0/ 72 | - download the binaries for `arm64`, `armv7`, `x86` and `x86_64`, e.g.: 73 | - `libindy_android_arm64_1.15.0.zip` 74 | - `libindy_android_armv7_1.15.0.zip` 75 | - `libindy_android_x86_1.15.0.zip` 76 | - `libindy_android_x86_64_1.15.0.zip` 77 | 4. Extract all downloaded ZIP files and copy `libindy.so` files to corresponding `jniLibs` directory 78 | - `libindy_arm64/lib/libindy.so` to `jniLibs/arm64-v8a/libindy.so` 79 | - `libindy_armv7/lib/libindy.so` to `jniLibs/armeabi-v7a/libindy.so` 80 | - `libindy_x86/lib/libindy.so` to `jniLibs/x86/libindy.so` 81 | - `libindy_x86_64/lib/libindy.so` to `jniLibs/x86_64/libindy.so` 82 | 5. Download the required JNA binaries from the [JNA GitHub repo](https://github.com/java-native-access/jna) 83 | - libindy version 1.15.0 works with version 5.5.0 of JNA. In this case the base url is: https://github.com/java-native-access/jna/tree/5.5.0/lib/native 84 | - download the binaries for `aarch64`, `armv7`, `x86`, `x86-64`, e.g.: 85 | - `android-aarch64.jar` 86 | - `android-armv7.jar` 87 | - `android-x86-64.jar` 88 | - `android-x86.jar` 89 | 6. Extract all downloaded JAR files and copy `libjnidispatch.so` to corresponding `jniLibs` directory 90 | - You can extract the `.so` file from the jar using the `jar` command. e.g. `jar xf android-x86.jar` 91 | - `libjnidispatch.so` from `android-aarch64.jar` to `jniLibs/arm64-v8a/libjnidispatch.so` 92 | - `libjnidispatch.so` from `android-armv7.jar` to `jniLibs/armeabi-v7a/libjnidispatch.so` 93 | - `libjnidispatch.so` from `android-x86.jar` to `jniLibs/x86/libjnidispatch.so` 94 | - `libjnidispatch.so` from `android-x86-64.jar` to `jniLibs/x86_64/libjnidispatch.so` 95 | 96 | ### 5. Load indy library 97 | 98 | Add the following to `MainActivity.java`: 99 | 100 | ```java 101 | 102 | //... 103 | 104 | import android.os.Bundle; 105 | import android.system.ErrnoException; 106 | import android.system.Os; 107 | import java.io.File; 108 | 109 | public class MainActivity extends ReactActivity { 110 | //... 111 | 112 | @Override 113 | protected void onCreate(Bundle savedInstanceState) { 114 | super.onCreate(savedInstanceState); 115 | 116 | try { 117 | Os.setenv("EXTERNAL_STORAGE", getExternalFilesDir(null).getAbsolutePath(), true); 118 | System.loadLibrary("indy"); 119 | } catch (ErrnoException e) { 120 | e.printStackTrace(); 121 | } 122 | } 123 | } 124 | ``` 125 | 126 | ## iOS 127 | 128 | 1. Install CocoaPods dependencies: 129 | ``` 130 | pod install --project-directory=ios/ 131 | ``` 132 | 133 | 2. Create `Frameworks` folder in your project's `ios/Pods` directory and copy `Indy.framework` into that directory. 134 | 135 | 3. [Optional] Most projects have `ios/Pods` ignored in their `.gitignore`. This is good practice, however this means the framework would need to be added after every clone. To prevent this you can "unignore" the Frameworks directory: 136 | 137 | ```.gitignore 138 | ios/Pods/ 139 | !ios/Pods/Frameworks 140 | ``` 141 | 142 | 4. Add `Indy.framework` as dependency into your project. Open `.xcworkspace` file in Xcode and in your project settings, tab General, section Frameworks, Libraries, and Embedded Content, click on plus. Then select Add Other -> Add files... and navigate to `Indy.framework` file on your disk. 143 | 144 | > Beware that the Indy SDK repository does not have the "Build Libraries for Distribution" enabled by default. If that setting is disabled the version of Swift your project uses must be the same as the version of Swift used to compile `Indy.framework`. From Swift 5.0 onwards, building the library with that setting enabled will allow to use an `Indy.framework` build that is compiled with a different version of Swift as your project. See https://stackoverflow.com/a/63305234/10552895 for more info. 145 | 146 | ## Usage 147 | 148 | ```javascript 149 | import indy from 'rn-indy-sdk' 150 | 151 | await indy.createWallet({ id: 'wallet-123' }, { key: 'key' }) 152 | ``` 153 | 154 | You can see example project here https://github.com/jakubkoci/UseReactNativeIndySdk/. It currently shows only usage on Android. 155 | 156 | ## Known Errors 157 | 158 | ### Add setup of external storage permissions (Android) 159 | 160 | I found an error with permission while calling `createWallet` when I was testing this package: 161 | 162 | ``` 163 | 2020-01-27 16:25:02.300 9955-10044/com.usereactnativeindysdk E/log_panics: thread 'unnamed' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 13, kind: PermissionDenied, message: "Permission denied" }': libcore/result.rs:945 164 | ``` 165 | 166 | Modify `onCreate` method in `MainActivity` of your project where you want to use this library in a following way: 167 | 168 | ```java 169 | public class MainActivity extends ReactActivity { 170 | ... 171 | @Override 172 | protected void onCreate(Bundle savedInstanceState) { 173 | ... 174 | File externalFilesDir = getExternalFilesDir(null); 175 | String path = externalFilesDir.getAbsolutePath(); 176 | System.out.println("externalFilesDir=" + path); 177 | 178 | try { 179 | Os.setenv("EXTERNAL_STORAGE", path, true); 180 | } catch (ErrnoException e) { 181 | e.printStackTrace(); 182 | } 183 | ... 184 | } 185 | ... 186 | } 187 | ``` 188 | 189 | This should resolve the issue with permissions. 190 | -------------------------------------------------------------------------------- /android/README.md: -------------------------------------------------------------------------------- 1 | README 2 | ====== 3 | 4 | If you want to publish the lib as a maven dependency, follow these steps before publishing a new version to npm: 5 | 6 | 1. Be sure to have the Android [SDK](https://developer.android.com/studio/index.html) and [NDK](https://developer.android.com/ndk/guides/index.html) installed 7 | 2. Be sure to have a `local.properties` file in this folder that points to the Android SDK and NDK 8 | ``` 9 | ndk.dir=/Users/{username}/Library/Android/sdk/ndk-bundle 10 | sdk.dir=/Users/{username}/Library/Android/sdk 11 | ``` 12 | 3. Delete the `maven` folder 13 | 4. Run `./gradlew installArchives` 14 | 5. Verify that latest set of generated files is in the maven folder with the correct version number 15 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2019 ABSA Group Limited 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | // android/build.gradle 18 | 19 | // based on: 20 | // 21 | // * https://github.com/facebook/react-native/blob/0.60-stable/template/android/build.gradle 22 | // original location: 23 | // - https://github.com/facebook/react-native/blob/0.58-stable/local-cli/templates/HelloWorld/android/build.gradle 24 | // 25 | // * https://github.com/facebook/react-native/blob/0.60-stable/template/android/app/build.gradle 26 | // original location: 27 | // - https://github.com/facebook/react-native/blob/0.58-stable/local-cli/templates/HelloWorld/android/app/build.gradle 28 | 29 | def DEFAULT_COMPILE_SDK_VERSION = 28 30 | def DEFAULT_BUILD_TOOLS_VERSION = '28.0.3' 31 | def DEFAULT_MIN_SDK_VERSION = 16 32 | def DEFAULT_TARGET_SDK_VERSION = 28 33 | 34 | def safeExtGet(prop, fallback) { 35 | rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback 36 | } 37 | 38 | apply plugin: 'com.android.library' 39 | apply plugin: 'maven' 40 | 41 | buildscript { 42 | // The Android Gradle plugin is only required when opening the android folder stand-alone. 43 | // This avoids unnecessary downloads and potential conflicts when the library is included as a 44 | // module dependency in an application project. 45 | // ref: https://docs.gradle.org/current/userguide/tutorial_using_tasks.html#sec:build_script_external_dependencies 46 | if (project == rootProject) { 47 | repositories { 48 | google() 49 | jcenter() 50 | } 51 | dependencies { 52 | classpath 'com.android.tools.build:gradle:3.4.1' 53 | } 54 | } 55 | } 56 | 57 | apply plugin: 'com.android.library' 58 | apply plugin: 'maven' 59 | 60 | android { 61 | compileSdkVersion safeExtGet('compileSdkVersion', DEFAULT_COMPILE_SDK_VERSION) 62 | buildToolsVersion safeExtGet('buildToolsVersion', DEFAULT_BUILD_TOOLS_VERSION) 63 | defaultConfig { 64 | minSdkVersion safeExtGet('minSdkVersion', DEFAULT_MIN_SDK_VERSION) 65 | targetSdkVersion safeExtGet('targetSdkVersion', DEFAULT_TARGET_SDK_VERSION) 66 | versionCode 1 67 | versionName "1.0" 68 | } 69 | lintOptions { 70 | abortOnError false 71 | } 72 | } 73 | 74 | repositories { 75 | // ref: https://www.baeldung.com/maven-local-repository 76 | mavenLocal() 77 | maven { 78 | url 'https://repo.sovrin.org/repository/maven-public' 79 | } 80 | maven { 81 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 82 | url "$rootDir/../node_modules/react-native/android" 83 | } 84 | maven { 85 | // Android JSC is installed from npm 86 | url "$rootDir/../node_modules/jsc-android/dist" 87 | } 88 | google() 89 | jcenter() 90 | } 91 | 92 | dependencies { 93 | //noinspection GradleDynamicVersion 94 | implementation 'com.facebook.react:react-native:+' // From node_modules 95 | implementation 'org.hyperledger:indy:1.15.0' 96 | implementation 'com.google.code.gson:gson:2.8.5' 97 | } 98 | 99 | def configureReactNativePom(def pom) { 100 | def packageJson = new groovy.json.JsonSlurper().parseText(file('../package.json').text) 101 | 102 | pom.project { 103 | name packageJson.title 104 | artifactId packageJson.name 105 | version = packageJson.version 106 | group = "com.reactlibrary" 107 | description packageJson.description 108 | url packageJson.repository.baseUrl 109 | 110 | licenses { 111 | license { 112 | name packageJson.license 113 | url packageJson.repository.baseUrl + '/blob/master/' + packageJson.licenseFilename 114 | distribution 'repo' 115 | } 116 | } 117 | 118 | developers { 119 | developer { 120 | id packageJson.author.username 121 | name packageJson.author.name 122 | } 123 | } 124 | } 125 | } 126 | 127 | afterEvaluate { project -> 128 | // some Gradle build hooks ref: 129 | // https://www.oreilly.com/library/view/gradle-beyond-the/9781449373801/ch03.html 130 | task androidJavadoc(type: Javadoc) { 131 | source = android.sourceSets.main.java.srcDirs 132 | classpath += files(android.bootClasspath) 133 | classpath += files(project.getConfigurations().getByName('compile').asList()) 134 | include '**/*.java' 135 | } 136 | 137 | task androidJavadocJar(type: Jar, dependsOn: androidJavadoc) { 138 | classifier = 'javadoc' 139 | from androidJavadoc.destinationDir 140 | } 141 | 142 | task androidSourcesJar(type: Jar) { 143 | classifier = 'sources' 144 | from android.sourceSets.main.java.srcDirs 145 | include '**/*.java' 146 | } 147 | 148 | android.libraryVariants.all { variant -> 149 | def name = variant.name.capitalize() 150 | def javaCompileTask = variant.javaCompileProvider.get() 151 | 152 | task "jar${name}"(type: Jar, dependsOn: javaCompileTask) { 153 | from javaCompileTask.destinationDir 154 | } 155 | } 156 | 157 | artifacts { 158 | archives androidSourcesJar 159 | archives androidJavadocJar 160 | } 161 | 162 | task installArchives(type: Upload) { 163 | configuration = configurations.archives 164 | repositories.mavenDeployer { 165 | // Deploy to react-native-event-bridge/maven, ready to publish to npm 166 | repository url: "file://${projectDir}/../android/maven" 167 | configureReactNativePom pom 168 | } 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbsaOSS/rn-indy-sdk/461094c3cf9f10556080ade9a0825270e79f236f/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Jan 27 13:04:49 CET 2020 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip 7 | -------------------------------------------------------------------------------- /android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 16 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /android/src/main/java/com/reactlibrary/IndySdkModule.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 ABSA Group Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.reactlibrary; 18 | 19 | import android.annotation.TargetApi; 20 | import android.util.Log; 21 | 22 | import com.facebook.react.bridge.Promise; 23 | import com.facebook.react.bridge.ReactApplicationContext; 24 | import com.facebook.react.bridge.ReactContextBaseJavaModule; 25 | import com.facebook.react.bridge.ReactMethod; 26 | 27 | import com.facebook.react.bridge.ReadableArray; 28 | import com.facebook.react.bridge.WritableArray; 29 | import com.facebook.react.bridge.WritableNativeArray; 30 | import com.google.gson.Gson; 31 | import com.google.gson.JsonElement; 32 | import com.google.gson.JsonObject; 33 | 34 | import org.hyperledger.indy.sdk.IndyException; 35 | import org.hyperledger.indy.sdk.ErrorCode; 36 | import org.hyperledger.indy.sdk.anoncreds.Anoncreds; 37 | import org.hyperledger.indy.sdk.anoncreds.AnoncredsResults; 38 | import org.hyperledger.indy.sdk.anoncreds.AnoncredsResults.IssuerCreateSchemaResult; 39 | import org.hyperledger.indy.sdk.anoncreds.AnoncredsResults.IssuerCreateAndStoreCredentialDefResult; 40 | import org.hyperledger.indy.sdk.anoncreds.AnoncredsResults.IssuerCreateCredentialResult; 41 | import org.hyperledger.indy.sdk.blob_storage.BlobStorageReader; 42 | import org.hyperledger.indy.sdk.crypto.Crypto; 43 | import org.hyperledger.indy.sdk.crypto.CryptoResults; 44 | import org.hyperledger.indy.sdk.did.Did; 45 | import org.hyperledger.indy.sdk.did.DidResults; 46 | import org.hyperledger.indy.sdk.ledger.Ledger; 47 | import org.hyperledger.indy.sdk.ledger.LedgerResults; 48 | import org.hyperledger.indy.sdk.non_secrets.WalletRecord; 49 | import org.hyperledger.indy.sdk.non_secrets.WalletSearch; 50 | import org.hyperledger.indy.sdk.pairwise.Pairwise; 51 | import org.hyperledger.indy.sdk.pool.Pool; 52 | import org.hyperledger.indy.sdk.wallet.Wallet; 53 | import org.hyperledger.indy.sdk.anoncreds.CredentialsSearchForProofReq; 54 | 55 | import java.util.Map; 56 | import java.util.concurrent.ConcurrentHashMap; 57 | import java.util.concurrent.ExecutionException; 58 | 59 | @TargetApi(24) 60 | public class IndySdkModule extends ReactContextBaseJavaModule { 61 | 62 | private static final String TAG = "IndySdk"; 63 | private final ReactApplicationContext reactContext; 64 | 65 | private static Map walletMap = new ConcurrentHashMap<>(); 66 | private static Map walletIdToHandleMap = new ConcurrentHashMap<>(); 67 | private static Map poolMap = new ConcurrentHashMap<>(); 68 | private static Map poolNameToHandleMap = new ConcurrentHashMap<>(); 69 | private static Map searchMap = new ConcurrentHashMap<>(); 70 | private Map credentialSearchMap; 71 | // Java wrapper does not expose credentialSearchHandle 72 | private int credentialSearchIterator = 0; 73 | 74 | 75 | public IndySdkModule(ReactApplicationContext reactContext) { 76 | super(reactContext); 77 | this.reactContext = reactContext; 78 | this.credentialSearchMap = new ConcurrentHashMap<>(); 79 | } 80 | 81 | @Override 82 | public String getName() { 83 | return "IndySdk"; 84 | } 85 | 86 | // wallet 87 | 88 | @ReactMethod 89 | public void createWallet(String configJson, String credentialsJson, Promise promise) { 90 | try { 91 | Wallet.createWallet(configJson, credentialsJson).get(); 92 | promise.resolve(null); 93 | } catch (Exception e) { 94 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 95 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 96 | } 97 | } 98 | 99 | @ReactMethod 100 | public void openWallet(String configJson, String credentialsJson, Promise promise) { 101 | // Retrieve wallet id 102 | Gson gson = new Gson(); 103 | JsonObject config = gson.fromJson(configJson, JsonObject.class); 104 | String walletId = config.get("id").getAsString(); 105 | 106 | // If wallet is already opened, return open wallet 107 | if (walletIdToHandleMap.containsKey(walletId)) { 108 | promise.resolve(walletIdToHandleMap.get(walletId)); 109 | } 110 | 111 | try { 112 | Wallet wallet = Wallet.openWallet(configJson, credentialsJson).get(); 113 | walletIdToHandleMap.put(walletId, wallet.getWalletHandle()); 114 | walletMap.put(wallet.getWalletHandle(), wallet); 115 | promise.resolve(wallet.getWalletHandle()); 116 | } catch (Exception e) { 117 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 118 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 119 | } 120 | } 121 | 122 | @ReactMethod 123 | public void closeWallet(int walletHandle, Promise promise) { 124 | try { 125 | Wallet wallet = walletMap.get(walletHandle); 126 | wallet.closeWallet().get(); 127 | walletMap.remove(walletHandle); 128 | 129 | // Remove wallet id mapping 130 | for (Map.Entry entry : walletIdToHandleMap.entrySet()) { 131 | if (entry.getValue().equals(walletHandle)) { 132 | walletIdToHandleMap.remove(entry.getKey()); 133 | break; 134 | } 135 | } 136 | 137 | promise.resolve(null); 138 | } catch (Exception e) { 139 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 140 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 141 | } 142 | } 143 | 144 | @ReactMethod 145 | public void deleteWallet(String configJson, String credentialsJson, Promise promise) { 146 | try { 147 | Wallet.deleteWallet(configJson, credentialsJson).get(); 148 | promise.resolve(null); 149 | } catch (Exception e) { 150 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 151 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 152 | } 153 | } 154 | 155 | // did 156 | 157 | @ReactMethod 158 | public void listMyDidsWithMeta(int walletHandle, Promise promise) { 159 | try { 160 | Wallet wallet = walletMap.get(walletHandle); 161 | String listDidsWithMetaJson = Did.getListMyDidsWithMeta(wallet).get(); 162 | promise.resolve(listDidsWithMetaJson); 163 | } catch (Exception e) { 164 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 165 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 166 | } 167 | } 168 | 169 | @ReactMethod 170 | public void setDidMetadata(int walletHandle, String did, String metadataJson, Promise promise) { 171 | try { 172 | Wallet wallet = walletMap.get(walletHandle); 173 | Did.setDidMetadata(wallet, did, metadataJson).get(); 174 | promise.resolve(null); 175 | } catch (Exception e) { 176 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 177 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 178 | } 179 | } 180 | 181 | @ReactMethod 182 | public void createAndStoreMyDid(int walletHandle, String didJson, Promise promise) { 183 | try { 184 | Wallet wallet = walletMap.get(walletHandle); 185 | DidResults.CreateAndStoreMyDidResult createMyDidResult = Did.createAndStoreMyDid(wallet, didJson).get(); 186 | String myDid = createMyDidResult.getDid(); 187 | String myVerkey = createMyDidResult.getVerkey(); 188 | WritableArray response = new WritableNativeArray(); 189 | response.pushString(myDid); 190 | response.pushString(myVerkey); 191 | promise.resolve(response); 192 | } catch (Exception e) { 193 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 194 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 195 | } 196 | } 197 | 198 | @ReactMethod 199 | public void keyForDid(int poolHandle, int walletHandle, String did, Promise promise) { 200 | try { 201 | Wallet wallet = walletMap.get(walletHandle); 202 | Pool pool = poolMap.get(poolHandle); 203 | String receivedKey = Did.keyForDid(pool, wallet, did).get(); 204 | promise.resolve(receivedKey); 205 | } catch (Exception e) { 206 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 207 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 208 | } 209 | } 210 | 211 | @ReactMethod 212 | public void keyForLocalDid(int walletHandle, String did, Promise promise) { 213 | try { 214 | Wallet wallet = walletMap.get(walletHandle); 215 | String receivedKey = Did.keyForLocalDid(wallet, did).get(); 216 | promise.resolve(receivedKey); 217 | } catch (Exception e) { 218 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 219 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 220 | } 221 | } 222 | 223 | // pairwise 224 | @ReactMethod 225 | public void createPairwise(int walletHandle, String theirDid, String myDid, String metadata, Promise promise) { 226 | try { 227 | Wallet wallet = walletMap.get(walletHandle); 228 | Pairwise.createPairwise(wallet, theirDid, myDid, metadata).get(); 229 | promise.resolve(null); 230 | } catch (Exception e) { 231 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 232 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 233 | } 234 | } 235 | 236 | @ReactMethod 237 | public void getPairwise(int walletHandle, String theirDid, Promise promise) { 238 | try { 239 | Wallet wallet = walletMap.get(walletHandle); 240 | String receivedKey = Pairwise.getPairwise(wallet, theirDid).get(); 241 | promise.resolve(receivedKey); 242 | } catch (Exception e) { 243 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 244 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 245 | } 246 | } 247 | 248 | // crypto 249 | 250 | private byte[] readableArrayToBuffer(ReadableArray arr) { 251 | byte[] buffer = new byte[arr.size()]; 252 | for (int i = 0; i < arr.size(); i++) { 253 | buffer[i] = (byte) arr.getInt(i); 254 | } 255 | return buffer; 256 | } 257 | 258 | @ReactMethod 259 | public void cryptoAnonCrypt(String theirKey, ReadableArray message, Promise promise) { 260 | try { 261 | byte[] buffer = readableArrayToBuffer(message); 262 | byte[] encryptedData = Crypto.anonCrypt(theirKey, buffer).get(); 263 | WritableArray result = new WritableNativeArray(); 264 | for (byte b : encryptedData) { 265 | result.pushInt(b); 266 | } 267 | promise.resolve(result); 268 | } catch (Exception e) { 269 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 270 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 271 | } 272 | } 273 | 274 | @ReactMethod 275 | public void cryptoAnonDecrypt(int walletHandle, String recipientVk, ReadableArray encryptedMessage, Promise promise) { 276 | try { 277 | byte [] encryptedMessageBytes = readableArrayToBuffer(encryptedMessage); 278 | Wallet wallet = walletMap.get(walletHandle); 279 | byte[] decryptedData = Crypto.anonDecrypt(wallet, recipientVk, encryptedMessageBytes).get(); 280 | promise.resolve(decryptedData); 281 | } catch (Exception e) { 282 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 283 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 284 | } 285 | } 286 | 287 | @ReactMethod 288 | @Deprecated 289 | public void cryptoAuthCrypt(int walletHandle, String senderVk, String recipientVk, ReadableArray message, Promise promise) { 290 | try { 291 | byte[] buffer = readableArrayToBuffer(message); 292 | Wallet wallet = walletMap.get(walletHandle); 293 | byte[] encryptedData = Crypto.authCrypt(wallet, senderVk, recipientVk, buffer).get(); 294 | WritableArray result = new WritableNativeArray(); 295 | for (byte b : encryptedData) { 296 | result.pushInt(b); 297 | } 298 | promise.resolve(result); 299 | } catch (Exception e) { 300 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 301 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 302 | } 303 | } 304 | 305 | @ReactMethod 306 | @Deprecated 307 | public void cryptoAuthDecrypt(int walletHandle, String recipientVk, ReadableArray encryptedMessage, Promise promise) { 308 | try { 309 | byte[] encryptedMessageBytes = readableArrayToBuffer(encryptedMessage); 310 | Wallet wallet = walletMap.get(walletHandle); 311 | CryptoResults.AuthDecryptResult decryptedResult = Crypto.authDecrypt(wallet, recipientVk, encryptedMessageBytes).get(); 312 | String theirKey = decryptedResult.getVerkey(); 313 | 314 | WritableArray decryptedData = new WritableNativeArray(); 315 | for (byte b : decryptedResult.getDecryptedMessage()) { 316 | decryptedData.pushInt(b); 317 | } 318 | 319 | WritableArray response = new WritableNativeArray(); 320 | response.pushString(theirKey); 321 | response.pushArray(decryptedData); 322 | promise.resolve(response); 323 | } catch (Exception e) { 324 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 325 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 326 | } 327 | } 328 | 329 | @ReactMethod 330 | public void cryptoSign(int walletHandle, String signerVk, ReadableArray messageRaw, Promise promise) { 331 | try { 332 | Wallet wallet = walletMap.get(walletHandle); 333 | byte[] buffer = readableArrayToBuffer(messageRaw); 334 | byte[] signature = Crypto.cryptoSign(wallet, signerVk, buffer).get(); 335 | WritableArray result = new WritableNativeArray(); 336 | for (byte b : signature) { 337 | result.pushInt(b); 338 | } 339 | promise.resolve(result); 340 | } catch (Exception e) { 341 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 342 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 343 | } 344 | } 345 | 346 | @ReactMethod 347 | public void cryptoVerify(String signerVk, ReadableArray messageRaw, ReadableArray signatureRaw, Promise promise) { 348 | try { 349 | byte[] messageBuf = readableArrayToBuffer(messageRaw); 350 | byte[] sigBuf = readableArrayToBuffer(signatureRaw); 351 | boolean valid = Crypto.cryptoVerify(signerVk, messageBuf, sigBuf).get(); 352 | 353 | promise.resolve(valid); 354 | } catch (Exception e) { 355 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 356 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 357 | } 358 | } 359 | 360 | 361 | @ReactMethod 362 | public void packMessage(int walletHandle, ReadableArray message, ReadableArray receiverKeys, String senderVk, Promise promise) { 363 | try { 364 | Wallet wallet = walletMap.get(walletHandle); 365 | byte[] buffer = readableArrayToBuffer(message); 366 | 367 | String[] keys = new String[receiverKeys.size()]; 368 | for (int i = 0; i < receiverKeys.size(); i++) { 369 | keys[i] = receiverKeys.getString(i); 370 | } 371 | Gson gson = new Gson(); 372 | String receiverKeysJson = gson.toJson(keys); 373 | 374 | byte[] jwe = Crypto.packMessage(wallet, receiverKeysJson, senderVk, buffer).get(); 375 | WritableArray result = new WritableNativeArray(); 376 | for (byte b : jwe) { 377 | result.pushInt(b); 378 | } 379 | promise.resolve(result); 380 | } catch (Exception e) { 381 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 382 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 383 | } 384 | } 385 | 386 | @ReactMethod 387 | public void unpackMessage(int walletHandle, ReadableArray jwe, Promise promise) { 388 | try { 389 | Wallet wallet = walletMap.get(walletHandle); 390 | byte[] buffer = readableArrayToBuffer(jwe); 391 | byte[] res = Crypto.unpackMessage(wallet, buffer).get(); 392 | 393 | WritableArray result = new WritableNativeArray(); 394 | for (byte b : res) { 395 | result.pushInt(b); 396 | } 397 | promise.resolve(result); 398 | } catch (Exception e) { 399 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 400 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 401 | } 402 | } 403 | 404 | // pool 405 | 406 | @ReactMethod 407 | public void setProtocolVersion(int protocolVersion, Promise promise) { 408 | try { 409 | Pool.setProtocolVersion(protocolVersion).get(); 410 | promise.resolve(null); 411 | } catch (Exception e) { 412 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 413 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 414 | } 415 | } 416 | 417 | @ReactMethod 418 | public void createPoolLedgerConfig(String configName, String poolConfig, Promise promise) { 419 | try { 420 | Pool.createPoolLedgerConfig(configName, poolConfig).get(); 421 | promise.resolve(null); 422 | } catch (Exception e) { 423 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 424 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 425 | } 426 | } 427 | 428 | @ReactMethod 429 | public void openPoolLedger(String configName, String poolConfig, Promise promise) { 430 | try { 431 | if (poolNameToHandleMap.get(configName) != null){ 432 | promise.resolve(poolNameToHandleMap.get(configName)); 433 | 434 | } else { 435 | Pool pool = Pool.openPoolLedger(configName, poolConfig).get(); 436 | poolMap.put(pool.getPoolHandle(), pool); 437 | poolNameToHandleMap.put(configName, pool.getPoolHandle()); 438 | promise.resolve(pool.getPoolHandle()); 439 | } 440 | } catch (Exception e) { 441 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 442 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 443 | } 444 | } 445 | 446 | @ReactMethod 447 | public void closePoolLedger(int handle, Promise promise) { 448 | try { 449 | Pool pool = poolMap.get(handle); 450 | pool.closePoolLedger().get(); 451 | poolMap.remove(handle); 452 | 453 | // Remove pool id mapping 454 | for (Map.Entry entry : poolNameToHandleMap.entrySet()) { 455 | if (entry.getValue().equals(handle)) { 456 | poolNameToHandleMap.remove(entry.getKey()); 457 | break; 458 | } 459 | } 460 | 461 | promise.resolve(null); 462 | } catch (Exception e) { 463 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 464 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 465 | } 466 | } 467 | 468 | // ledger 469 | 470 | @ReactMethod 471 | public void submitRequest(int poolHandle, String requestJson, Promise promise) { 472 | try { 473 | Pool pool = poolMap.get(poolHandle); 474 | String response = Ledger.submitRequest(pool, requestJson).get(); 475 | promise.resolve(response); 476 | } catch (Exception e) { 477 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 478 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 479 | } 480 | } 481 | 482 | @ReactMethod 483 | public void signRequest(int walletHandle, String submitterDid, String requestJson, Promise promise) { 484 | try { 485 | Wallet wallet = walletMap.get(walletHandle); 486 | String request = Ledger.signRequest(wallet, submitterDid, requestJson).get(); 487 | promise.resolve(request); 488 | } catch (Exception e) { 489 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 490 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 491 | } 492 | } 493 | 494 | @ReactMethod 495 | public void buildSchemaRequest(String submitterDid, String data, Promise promise) { 496 | try { 497 | String request = Ledger.buildSchemaRequest(submitterDid, data).get(); 498 | promise.resolve(request); 499 | } catch (Exception e) { 500 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 501 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 502 | } 503 | } 504 | 505 | @ReactMethod 506 | public void buildGetSchemaRequest(String submitterDid, String id, Promise promise) { 507 | try { 508 | String request = Ledger.buildGetSchemaRequest(submitterDid, id).get(); 509 | promise.resolve(request); 510 | } catch (Exception e) { 511 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 512 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 513 | } 514 | } 515 | 516 | @ReactMethod 517 | public void parseGetSchemaResponse(String getSchemaResponse, Promise promise) { 518 | try { 519 | LedgerResults.ParseResponseResult ledgerResult = Ledger.parseGetSchemaResponse(getSchemaResponse).get(); 520 | WritableArray result = new WritableNativeArray(); 521 | result.pushString(ledgerResult.getId()); 522 | result.pushString(ledgerResult.getObjectJson()); 523 | promise.resolve(result); 524 | } catch (Exception e) { 525 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 526 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 527 | } 528 | } 529 | 530 | @ReactMethod 531 | public void buildCredDefRequest(String submitterDid, String data, Promise promise) { 532 | try { 533 | String request = Ledger.buildCredDefRequest(submitterDid, data).get(); 534 | promise.resolve(request); 535 | } catch (Exception e) { 536 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 537 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 538 | } 539 | } 540 | 541 | @ReactMethod 542 | public void buildGetCredDefRequest(String submitterDid, String id, Promise promise) { 543 | try { 544 | String request = Ledger.buildGetCredDefRequest(submitterDid, id).get(); 545 | promise.resolve(request); 546 | } catch (Exception e) { 547 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 548 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 549 | } 550 | } 551 | 552 | @ReactMethod 553 | public void parseGetCredDefResponse(String getCredDefResponse, Promise promise) { 554 | try { 555 | LedgerResults.ParseResponseResult ledgerResult = Ledger.parseGetCredDefResponse(getCredDefResponse).get(); 556 | WritableArray result = new WritableNativeArray(); 557 | result.pushString(ledgerResult.getId()); 558 | result.pushString(ledgerResult.getObjectJson()); 559 | promise.resolve(result); 560 | } catch (Exception e) { 561 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 562 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 563 | } 564 | } 565 | 566 | @ReactMethod 567 | public void buildGetAttribRequest(String submitterDid, String targetDid, String raw, String hash, String enc, Promise promise) { 568 | try { 569 | String request = Ledger.buildGetAttribRequest(submitterDid, targetDid, raw, hash, enc).get(); 570 | promise.resolve(request); 571 | } catch (Exception e) { 572 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 573 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 574 | } 575 | } 576 | 577 | @ReactMethod 578 | public void buildGetNymRequest(String submitterDid, String targetDid, Promise promise) { 579 | try { 580 | String request = Ledger.buildGetNymRequest(submitterDid, targetDid).get(); 581 | promise.resolve(request); 582 | } catch (Exception e) { 583 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 584 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 585 | } 586 | } 587 | 588 | @ReactMethod 589 | public void parseGetNymResponse(String response, Promise promise) { 590 | try { 591 | String parsedResponse = Ledger.parseGetNymResponse(response).get(); 592 | promise.resolve(parsedResponse); 593 | } catch (Exception e) { 594 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 595 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 596 | } 597 | } 598 | 599 | @ReactMethod 600 | public void appendTxnAuthorAgreementAcceptanceToRequest(String requestJson, String text, String version, String taaDigest, String mechanism, int time, Promise promise) { 601 | try { 602 | String request = Ledger.appendTxnAuthorAgreementAcceptanceToRequest(requestJson, text, version, taaDigest, mechanism, time).get(); 603 | promise.resolve(request); 604 | } catch (Exception e) { 605 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 606 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 607 | } 608 | } 609 | 610 | @ReactMethod 611 | public void buildGetTxnAuthorAgreementRequest(String submitterDid, String data, Promise promise) { 612 | try { 613 | String request = Ledger.buildGetTxnAuthorAgreementRequest(submitterDid, data).get(); 614 | promise.resolve(request); 615 | } catch (Exception e) { 616 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 617 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 618 | } 619 | } 620 | 621 | // anoncreds 622 | 623 | @ReactMethod 624 | public void issuerCreateSchema(String issuerDid, String name, String version, String attrs, Promise promise) { 625 | try { 626 | IssuerCreateSchemaResult schemaResult = Anoncreds.issuerCreateSchema(issuerDid, name, version, attrs).get(); 627 | WritableArray response = new WritableNativeArray(); 628 | response.pushString(schemaResult.getSchemaId()); 629 | response.pushString(schemaResult.getSchemaJson()); 630 | promise.resolve(response); 631 | } catch(Exception e) { 632 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 633 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 634 | } 635 | } 636 | 637 | @ReactMethod 638 | public void issuerCreateAndStoreCredentialDef(int walletHandle, String issuerDid, String schemaJson, String tag, String signatureType, String configJson, Promise promise) { 639 | try { 640 | Wallet wallet = walletMap.get(walletHandle); 641 | IssuerCreateAndStoreCredentialDefResult schemaResult = Anoncreds.issuerCreateAndStoreCredentialDef(wallet, issuerDid, schemaJson, tag, signatureType, configJson).get(); 642 | WritableArray response = new WritableNativeArray(); 643 | response.pushString(schemaResult.getCredDefId()); 644 | response.pushString(schemaResult.getCredDefJson()); 645 | promise.resolve(response); 646 | } catch(Exception e) { 647 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 648 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 649 | } 650 | } 651 | 652 | @ReactMethod 653 | public void issuerCreateCredential(int walletHandle, String credOffer, String credReq, String credvalues, String revRegId, int blobStorageReaderHandle, Promise promise) { 654 | try { 655 | Wallet wallet = walletMap.get(walletHandle); 656 | IssuerCreateCredentialResult createCredResult = Anoncreds.issuerCreateCredential(wallet, credOffer, credReq, credvalues, revRegId, blobStorageReaderHandle).get(); 657 | WritableArray response = new WritableNativeArray(); 658 | response.pushString(createCredResult.getCredentialJson()); 659 | response.pushString(createCredResult.getRevocId()); 660 | response.pushString(createCredResult.getRevocRegDeltaJson()); 661 | promise.resolve(response); 662 | } catch(Exception e) { 663 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 664 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 665 | } 666 | } 667 | 668 | @ReactMethod 669 | public void issuerCreateCredentialOffer(int walletHandle, String credDefId, Promise promise) { 670 | try { 671 | Wallet wallet = walletMap.get(walletHandle); 672 | String response = Anoncreds.issuerCreateCredentialOffer(wallet, credDefId).get(); 673 | promise.resolve(response); 674 | } catch(Exception e) { 675 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 676 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 677 | } 678 | } 679 | 680 | @ReactMethod 681 | public void proverCreateMasterSecret(int walletHandle, String masterSecretId, Promise promise) { 682 | try { 683 | Wallet wallet = walletMap.get(walletHandle); 684 | String outputMasterSecretId = Anoncreds.proverCreateMasterSecret(wallet, masterSecretId).get(); 685 | promise.resolve(outputMasterSecretId); 686 | } catch (Exception e) { 687 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 688 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 689 | } 690 | } 691 | 692 | @ReactMethod 693 | public void proverCreateCredentialReq(int walletHandle, String proverDid, String credentialOfferJson, String credentialDefJson, String masterSecretId, Promise promise) { 694 | try { 695 | Wallet wallet = walletMap.get(walletHandle); 696 | AnoncredsResults.ProverCreateCredentialRequestResult credentialRequestResult = Anoncreds.proverCreateCredentialReq(wallet, proverDid, credentialOfferJson, credentialDefJson, masterSecretId).get(); 697 | WritableArray response = new WritableNativeArray(); 698 | response.pushString(credentialRequestResult.getCredentialRequestJson()); 699 | response.pushString(credentialRequestResult.getCredentialRequestMetadataJson()); 700 | promise.resolve(response); 701 | } catch (Exception e) { 702 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 703 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 704 | } 705 | } 706 | 707 | @ReactMethod 708 | public void proverStoreCredential(int walletHandle, String credId, String credReqMetadataJson, String credJson, String credDefJson, String revRegDefJson, Promise promise) { 709 | try { 710 | Wallet wallet = walletMap.get(walletHandle); 711 | String newCredId = Anoncreds.proverStoreCredential(wallet, credId, credReqMetadataJson, credJson, credDefJson, revRegDefJson).get(); 712 | promise.resolve(newCredId); 713 | } catch (Exception e) { 714 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 715 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 716 | } 717 | } 718 | 719 | @ReactMethod 720 | public void proverGetCredential(int walletHandle, String credId, Promise promise) { 721 | try { 722 | Wallet wallet = walletMap.get(walletHandle); 723 | String credential = Anoncreds.proverGetCredential(wallet, credId).get(); 724 | promise.resolve(credential); 725 | } catch (Exception e) { 726 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 727 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 728 | } 729 | } 730 | 731 | @ReactMethod 732 | public void proverGetCredentials(int walletHandle, String filter, Promise promise) { 733 | try { 734 | Wallet wallet = walletMap.get(walletHandle); 735 | String credentials = Anoncreds.proverGetCredentials(wallet, filter).get(); 736 | promise.resolve(credentials); 737 | } catch (Exception e) { 738 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 739 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 740 | } 741 | } 742 | 743 | @ReactMethod 744 | public void proverGetCredentialsForProofReq( 745 | int walletHandle, 746 | String proofRequest, 747 | Promise promise 748 | ) { 749 | try { 750 | Wallet wallet = walletMap.get(walletHandle); 751 | String credentials = Anoncreds.proverGetCredentialsForProofReq( 752 | wallet, 753 | proofRequest 754 | ).get(); 755 | promise.resolve(credentials); 756 | } catch (Exception e) { 757 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 758 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 759 | } 760 | } 761 | 762 | @ReactMethod 763 | public void proverSearchCredentialsForProofReq(int walletHandle, String proofRequest, String extraQuery, Promise promise) { 764 | try { 765 | int searchHandle = credentialSearchIterator++; 766 | Wallet wallet = walletMap.get(walletHandle); 767 | CredentialsSearchForProofReq search = CredentialsSearchForProofReq.open(wallet, proofRequest, extraQuery).get(); 768 | credentialSearchMap.put(searchHandle, search); 769 | promise.resolve(searchHandle); 770 | } catch (Exception e) { 771 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 772 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 773 | } 774 | } 775 | 776 | @ReactMethod 777 | public void proverFetchCredentialsForProofReq(int searchHandle, String itemReferent, int count, Promise promise) { 778 | try { 779 | CredentialsSearchForProofReq search = credentialSearchMap.get(searchHandle); 780 | String recordsJson = search.fetchNextCredentials(itemReferent, count).get(); 781 | promise.resolve(recordsJson); 782 | } catch (Exception e) { 783 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 784 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 785 | } 786 | } 787 | 788 | @ReactMethod 789 | public void proverCloseCredentialsSearchForProofReq(int searchHandle, Promise promise) { 790 | try { 791 | CredentialsSearchForProofReq search = credentialSearchMap.get(searchHandle); 792 | search.close(); 793 | credentialSearchMap.remove(searchHandle); 794 | promise.resolve(null); 795 | } catch (Exception e) { 796 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 797 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 798 | } 799 | } 800 | 801 | @ReactMethod 802 | public void proverCreateProof( 803 | int walletHandle, 804 | String proofRequest, 805 | String requestedCredentials, 806 | String masterSecret, 807 | String schemas, 808 | String credentialDefs, 809 | String revocStates, 810 | Promise promise 811 | ) { 812 | try { 813 | Wallet wallet = walletMap.get(walletHandle); 814 | String proofJson = Anoncreds.proverCreateProof( 815 | wallet, 816 | proofRequest, 817 | requestedCredentials, 818 | masterSecret, 819 | schemas, 820 | credentialDefs, 821 | revocStates 822 | ).get(); 823 | promise.resolve(proofJson); 824 | } catch (Exception e) { 825 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 826 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 827 | } 828 | } 829 | 830 | @ReactMethod 831 | public void verifierVerifyProof( 832 | String proofRequest, 833 | String proof, 834 | String schemas, 835 | String credentialDefs, 836 | String revocRegDefs, 837 | String revocRegs, 838 | Promise promise 839 | ) { 840 | try{ 841 | Boolean verified = Anoncreds.verifierVerifyProof(proofRequest, proof, schemas, credentialDefs, revocRegDefs, revocRegs).get(); 842 | 843 | promise.resolve(verified); 844 | } 845 | catch (Exception e) { 846 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 847 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 848 | } 849 | } 850 | 851 | // blob_storage 852 | 853 | @ReactMethod 854 | public void openBlobStorageReader(String type, String tailsWriterConfig, Promise promise) { 855 | try { 856 | BlobStorageReader response = BlobStorageReader.openReader(type, tailsWriterConfig).get(); 857 | promise.resolve(response.getBlobStorageReaderHandle()); 858 | } catch(Exception e) { 859 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 860 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 861 | } 862 | } 863 | 864 | // non_secrets 865 | 866 | @ReactMethod 867 | public void addWalletRecord(int walletHandle, String type, String id, String value, String tagsJson, Promise promise) { 868 | try { 869 | Wallet wallet = walletMap.get(walletHandle); 870 | WalletRecord.add(wallet, type, id, value, tagsJson).get(); 871 | promise.resolve(null); 872 | } catch (Exception e) { 873 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 874 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 875 | } 876 | } 877 | 878 | @ReactMethod 879 | public void updateWalletRecordValue(int walletHandle, String type, String id, String value, Promise promise) { 880 | try { 881 | Wallet wallet = walletMap.get(walletHandle); 882 | WalletRecord.updateValue(wallet, type, id, value).get(); 883 | promise.resolve(null); 884 | } catch (Exception e) { 885 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 886 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 887 | } 888 | } 889 | 890 | @ReactMethod 891 | public void updateWalletRecordTags(int walletHandle, String type, String id, String tagsJson, Promise promise) { 892 | try { 893 | Wallet wallet = walletMap.get(walletHandle); 894 | WalletRecord.updateTags(wallet, type, id, tagsJson).get(); 895 | promise.resolve(null); 896 | } catch (Exception e) { 897 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 898 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 899 | } 900 | } 901 | 902 | @ReactMethod 903 | public void addWalletRecordTags(int walletHandle, String type, String id, String tagsJson, Promise promise) { 904 | try { 905 | Wallet wallet = walletMap.get(walletHandle); 906 | WalletRecord.addTags(wallet, type, id, tagsJson).get(); 907 | promise.resolve(null); 908 | } catch (Exception e) { 909 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 910 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 911 | } 912 | } 913 | 914 | @ReactMethod 915 | public void deleteWalletRecordTags(int walletHandle, String type, String id, String tagNamesJson, Promise promise) { 916 | try { 917 | Wallet wallet = walletMap.get(walletHandle); 918 | WalletRecord.deleteTags(wallet, type, id, tagNamesJson).get(); 919 | promise.resolve(null); 920 | } catch (Exception e) { 921 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 922 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 923 | } 924 | } 925 | 926 | @ReactMethod 927 | public void deleteWalletRecord(int walletHandle, String type, String id, Promise promise) { 928 | try { 929 | Wallet wallet = walletMap.get(walletHandle); 930 | WalletRecord.delete(wallet, type, id).get(); 931 | promise.resolve(null); 932 | } catch (Exception e) { 933 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 934 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 935 | } 936 | } 937 | 938 | @ReactMethod 939 | public void getWalletRecord(int walletHandle, String type, String id, String optionsJson, Promise promise) { 940 | try { 941 | Wallet wallet = walletMap.get(walletHandle); 942 | String record = WalletRecord.get(wallet, type, id, optionsJson).get(); 943 | promise.resolve(record); 944 | } catch (Exception e) { 945 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 946 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 947 | } 948 | } 949 | 950 | @ReactMethod 951 | public void openWalletSearch(int walletHandle, String type, String queryJson, String optionsJson, Promise promise) { 952 | try { 953 | Wallet wallet = walletMap.get(walletHandle); 954 | WalletSearch search = WalletSearch.open(wallet, type, queryJson, optionsJson).get(); 955 | searchMap.put(search.getSearchHandle(), search); 956 | promise.resolve(search.getSearchHandle()); 957 | } catch (Exception e) { 958 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 959 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 960 | } 961 | } 962 | 963 | @ReactMethod 964 | public void fetchWalletSearchNextRecords(int walletHandle, int walletSearchHandle, int count, Promise promise) { 965 | try { 966 | Wallet wallet = walletMap.get(walletHandle); 967 | WalletSearch search = searchMap.get(walletSearchHandle); 968 | String recordsJson = WalletSearch.searchFetchNextRecords(wallet, search, count).get(); 969 | promise.resolve(recordsJson); 970 | } catch (Exception e) { 971 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 972 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 973 | } 974 | } 975 | 976 | @ReactMethod 977 | public void closeWalletSearch(int walletSearchHandle, Promise promise) { 978 | try { 979 | WalletSearch search = searchMap.get(walletSearchHandle); 980 | WalletSearch.closeSearch(search); 981 | searchMap.remove(walletSearchHandle); 982 | promise.resolve(null); 983 | } catch (Exception e) { 984 | IndySdkRejectResponse rejectResponse = new IndySdkRejectResponse(e); 985 | promise.reject(rejectResponse.getCode(), rejectResponse.toJson(), e); 986 | } 987 | } 988 | 989 | class IndySdkRejectResponse { 990 | private String name = "IndyError"; 991 | private int indyCode; 992 | private String indyName; 993 | private String message; 994 | private String indyCurrentErrorJson; 995 | private String indyMessage; 996 | private String indyBacktrace; 997 | 998 | private IndySdkRejectResponse(Throwable e) { 999 | // Indy bridge exposed API should return consistently only numeric code 1000 | // When we don't get IndyException and Indy SDK error code we return zero as default 1001 | indyCode = 0; 1002 | 1003 | if (e instanceof ExecutionException) { 1004 | Throwable cause = e.getCause(); 1005 | if (cause instanceof IndyException) { 1006 | IndyException indyException = (IndyException) cause; 1007 | indyCode = indyException.getSdkErrorCode(); 1008 | 1009 | ErrorCode errorCode = ErrorCode.valueOf(indyCode); 1010 | indyName = errorCode.toString(); 1011 | message = indyName; 1012 | // TODO: we can't extract indyCurrentErrorJson directly from indyError 1013 | // So we would need to extract it ourelf as done here 1014 | // https://github.com/hyperledger/indy-sdk/blob/bafa3bbcca2f7ef4cf5ae2aca01b1dbf7286b924/wrappers/java/src/main/java/org/hyperledger/indy/sdk/IndyException.java#L71-L83 1015 | indyMessage = indyException.getSdkMessage(); 1016 | indyBacktrace = indyException.getSdkBacktrace(); 1017 | } else { 1018 | Log.e(TAG, "Unhandled non IndyException", e); 1019 | } 1020 | } else { 1021 | Log.e(TAG, "Unhandled non ExecutionException", e); 1022 | } 1023 | } 1024 | 1025 | public String getCode() { 1026 | return String.valueOf(indyCode); 1027 | } 1028 | 1029 | public String getMessage() { 1030 | return message; 1031 | } 1032 | 1033 | public String toJson() { 1034 | Gson gson = new Gson(); 1035 | return gson.toJson(this); 1036 | } 1037 | } 1038 | } 1039 | -------------------------------------------------------------------------------- /android/src/main/java/com/reactlibrary/IndySdkPackage.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 ABSA Group Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.reactlibrary; 18 | 19 | import java.util.Arrays; 20 | import java.util.Collections; 21 | import java.util.List; 22 | 23 | import com.facebook.react.ReactPackage; 24 | import com.facebook.react.bridge.NativeModule; 25 | import com.facebook.react.bridge.ReactApplicationContext; 26 | import com.facebook.react.uimanager.ViewManager; 27 | import com.facebook.react.bridge.JavaScriptModule; 28 | 29 | public class IndySdkPackage implements ReactPackage { 30 | @Override 31 | public List createNativeModules(ReactApplicationContext reactContext) { 32 | return Arrays.asList(new IndySdkModule(reactContext)); 33 | } 34 | 35 | @Override 36 | public List createViewManagers(ReactApplicationContext reactContext) { 37 | return Collections.emptyList(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ios/IndySdk-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2019 ABSA Group Limited 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | // 18 | // Use this file to import your target's public headers that you would like to expose to Swift. 19 | // 20 | 21 | #import 22 | #import 23 | -------------------------------------------------------------------------------- /ios/IndySdk.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2019 ABSA Group Limited 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | 18 | #import 19 | 20 | #if __has_include() 21 | #import 22 | #elif __has_include("RCTViewManager.h") 23 | #import "RCTViewManager.h" 24 | #else 25 | #import "React/RCTViewManager.h" // Required when used as a Pod in a Swift project 26 | #endif 27 | 28 | // import RCTEventDispatcher 29 | #if __has_include() 30 | #import 31 | #elif __has_include("RCTEventDispatcher.h") 32 | #import "RCTEventDispatcher.h" 33 | #else 34 | #import "React/RCTEventDispatcher.h" // Required when used as a Pod in a Swift project 35 | #endif 36 | 37 | 38 | @interface RCT_EXTERN_MODULE(IndySdk, NSObject) 39 | 40 | RCT_EXTERN_METHOD(sampleMethod: (NSString *)stringArgument numberArgument:(nonnull NSNumber *)numberArgument 41 | resolver:(RCTPromiseResolveBlock)resolve 42 | rejecter:(RCTPromiseRejectBlock)reject) 43 | 44 | // wallet 45 | RCT_EXTERN_METHOD(createWallet: (NSString *)config credentials:(NSString *)credentials 46 | resolver:(RCTPromiseResolveBlock)resolve 47 | rejecter:(RCTPromiseRejectBlock)reject) 48 | 49 | RCT_EXTERN_METHOD(openWallet: (NSString *)config credentials:(NSString *)credentials 50 | resolver:(RCTPromiseResolveBlock)resolve 51 | rejecter:(RCTPromiseRejectBlock)reject) 52 | 53 | RCT_EXTERN_METHOD(closeWallet: (nonnull NSNumber *)walletHandle 54 | resolver:(RCTPromiseResolveBlock)resolve 55 | rejecter:(RCTPromiseRejectBlock)reject) 56 | 57 | RCT_EXTERN_METHOD(deleteWallet: (NSString *)config credentials:(NSString *)credentials 58 | resolver:(RCTPromiseResolveBlock)resolve 59 | rejecter:(RCTPromiseRejectBlock)reject) 60 | 61 | RCT_EXTERN_METHOD(exportWallet: (nonnull NSNumber *)walletHandle exportConfig:(NSString *)exportConfig 62 | resolver:(RCTPromiseResolveBlock)resolve 63 | rejecter:(RCTPromiseRejectBlock)reject) 64 | 65 | RCT_EXTERN_METHOD(importWallet: (NSString *)config credentials:(NSString *)credentials importConfig:(NSString *)importConfig 66 | resolver:(RCTPromiseResolveBlock)resolve 67 | rejecter:(RCTPromiseRejectBlock)reject) 68 | 69 | // did 70 | RCT_EXTERN_METHOD(createAndStoreMyDid: (NSString *)didJson walletHandle:(nonnull NSNumber *)walletHandle 71 | resolver:(RCTPromiseResolveBlock)resolve 72 | rejecter:(RCTPromiseRejectBlock)reject) 73 | 74 | RCT_EXTERN_METHOD(keyForDid: (NSString *)did poolHandle:(nonnull NSNumber *)poolHandle walletHandle:(nonnull NSNumber *)walletHandle 75 | resolver:(RCTPromiseResolveBlock)resolve 76 | rejecter:(RCTPromiseRejectBlock)reject) 77 | 78 | RCT_EXTERN_METHOD(keyForLocalDid: (NSString *)did walletHandle:(nonnull NSNumber *)walletHandle 79 | resolver:(RCTPromiseResolveBlock)resolve 80 | rejecter:(RCTPromiseRejectBlock)reject) 81 | 82 | RCT_EXTERN_METHOD(storeTheirDid: (NSString *)identityJSON walletHandle:(nonnull NSNumber *)walletHandle 83 | resolver:(RCTPromiseResolveBlock)resolve 84 | rejecter:(RCTPromiseRejectBlock)reject) 85 | 86 | // pairwise 87 | RCT_EXTERN_METHOD(createPairwise: (NSString *)theirDid myDid:(NSString *)myDid metadata:(NSString *)metadata walletHandle:(nonnull NSNumber *)walletHandle 88 | resolver:(RCTPromiseResolveBlock)resolve 89 | rejecter:(RCTPromiseRejectBlock)reject) 90 | 91 | RCT_EXTERN_METHOD(getPairwise: (NSString *)theirDid walletHandle:(nonnull NSNumber *)walletHandle 92 | resolver:(RCTPromiseResolveBlock)resolve 93 | rejecter:(RCTPromiseRejectBlock)reject) 94 | 95 | // crypto 96 | RCT_EXTERN_METHOD(cryptoAnonCrypt: (NSString *)message theirKey:(NSString *)theirKey 97 | resolver:(RCTPromiseResolveBlock)resolve 98 | rejecter:(RCTPromiseRejectBlock)reject) 99 | 100 | RCT_EXTERN_METHOD(cryptoAnonDecrypt: (NSArray *)encryptedMessage myKey:(NSString *)myKey walletHandle:(nonnull NSNumber *)walletHandle 101 | resolver:(RCTPromiseResolveBlock)resolve 102 | rejecter:(RCTPromiseRejectBlock)reject) 103 | 104 | RCT_EXTERN_METHOD(cryptoAuthCrypt: (NSString *)message myKey:(NSString *)myKey theirKey:(NSString *)theirKey walletHandle:(nonnull NSNumber *)walletHandle 105 | resolver:(RCTPromiseResolveBlock)resolve 106 | rejecter:(RCTPromiseRejectBlock)reject) 107 | 108 | RCT_EXTERN_METHOD(cryptoAuthDecrypt: (NSArray *)encryptedMessage myKey:(NSString *)myKey walletHandle:(nonnull NSNumber *)walletHandle 109 | resolver:(RCTPromiseResolveBlock)resolve 110 | rejecter:(RCTPromiseRejectBlock)reject) 111 | 112 | RCT_EXTERN_METHOD(cryptoSign: (nonnull NSNumber *)wh 113 | signerVk: (NSString *)signerVk 114 | message: (NSArray *)message 115 | resolver:(RCTPromiseResolveBlock)resolve 116 | rejecter:(RCTPromiseRejectBlock)reject 117 | ) 118 | 119 | RCT_EXTERN_METHOD(cryptoVerify: (NSString *)signerVk 120 | message: (NSArray *)message 121 | signature: (NSArray *)signature 122 | resolver:(RCTPromiseResolveBlock)resolve 123 | rejecter:(RCTPromiseRejectBlock)reject 124 | ) 125 | 126 | RCT_EXTERN_METHOD(packMessage: (nonnull NSNumber *)wh 127 | message: (NSArray *)message 128 | receiverKeys: (NSString *)receiverKeys 129 | senderVk: (NSString *)senderVk 130 | resolver:(RCTPromiseResolveBlock)resolve 131 | rejecter:(RCTPromiseRejectBlock)reject 132 | ) 133 | 134 | RCT_EXTERN_METHOD(unpackMessage: (nonnull NSNumber *)wh 135 | jwe: (NSArray *)jwe 136 | resolver:(RCTPromiseResolveBlock)resolve 137 | rejecter:(RCTPromiseRejectBlock)reject 138 | ) 139 | 140 | // pool 141 | RCT_EXTERN_METHOD(createPoolLedgerConfig: (NSString *)name poolConfig:(NSString *)poolConfig 142 | resolver:(RCTPromiseResolveBlock)resolve 143 | rejecter:(RCTPromiseRejectBlock)reject) 144 | 145 | RCT_EXTERN_METHOD(openLedger: (NSString *)name poolConfig:(nullable NSString *)poolConfig 146 | resolver:(RCTPromiseResolveBlock)resolve 147 | rejecter:(RCTPromiseRejectBlock)reject) 148 | 149 | RCT_EXTERN_METHOD(setProtocolVersion: (nonnull NSNumber *)protocolVersion 150 | resolver:(RCTPromiseResolveBlock)resolve 151 | rejecter:(RCTPromiseRejectBlock)reject) 152 | 153 | RCT_EXTERN_METHOD(closePoolLedger: (nonnull NSNumber *)poolHandle 154 | resolver:(RCTPromiseResolveBlock)resolve 155 | rejecter:(RCTPromiseRejectBlock)reject) 156 | 157 | // ledger 158 | 159 | RCT_EXTERN_METHOD(submitRequest: (NSString *)requestJSON poolHandle:(nonnull NSNumber *)poolHandle 160 | resolver:(RCTPromiseResolveBlock)resolve 161 | rejecter:(RCTPromiseRejectBlock)reject) 162 | 163 | RCT_EXTERN_METHOD(buildGetSchemaRequest: (NSString *)submitterDid id:(NSString *)id 164 | resolver:(RCTPromiseResolveBlock)resolve 165 | rejecter:(RCTPromiseRejectBlock)reject) 166 | 167 | RCT_EXTERN_METHOD(parseGetSchemaResponse: (NSString *)getSchemaResponse 168 | resolver:(RCTPromiseResolveBlock)resolve 169 | rejecter:(RCTPromiseRejectBlock)reject) 170 | 171 | RCT_EXTERN_METHOD(buildGetCredDefRequest: (NSString *)submitterDid id:(NSString *)id 172 | resolver:(RCTPromiseResolveBlock)resolve 173 | rejecter:(RCTPromiseRejectBlock)reject) 174 | 175 | RCT_EXTERN_METHOD(parseGetCredDefResponse: (NSString *)getCredDefResponse 176 | resolver:(RCTPromiseResolveBlock)resolve 177 | rejecter:(RCTPromiseRejectBlock)reject) 178 | 179 | RCT_EXTERN_METHOD(buildGetAttribRequest: (nullable NSString *)submitterDid 180 | targetDid:(NSString *)targetDid 181 | raw:(nullable NSString *)raw 182 | hash:(nullable NSString *)hash 183 | enc:(nullable NSString *)enc 184 | resolver:(RCTPromiseResolveBlock)resolve 185 | rejecter:(RCTPromiseRejectBlock)reject) 186 | 187 | RCT_EXTERN_METHOD(buildGetNymRequest: (nullable NSString *)submitterDid 188 | targetDid:(NSString *)targetDid 189 | resolver:(RCTPromiseResolveBlock)resolve 190 | rejecter:(RCTPromiseRejectBlock)reject 191 | ) 192 | 193 | RCT_EXTERN_METHOD(parseGetNymResponse: (NSString *)response 194 | resolver:(RCTPromiseResolveBlock)resolve 195 | rejecter:(RCTPromiseRejectBlock)reject 196 | ) 197 | 198 | // anoncreds 199 | 200 | RCT_EXTERN_METHOD(proverCreateMasterSecret: (NSString *)masterSecretId walletHandle:(nonnull NSNumber *)walletHandle 201 | resolver:(RCTPromiseResolveBlock)resolve 202 | rejecter:(RCTPromiseRejectBlock)reject) 203 | 204 | RCT_EXTERN_METHOD(proverCreateCredentialReq: (NSString *)credOfferJSON 205 | credentialDefJSON:(NSString *)credentialDefJSON 206 | proverDID:(NSString *)proverDID 207 | masterSecretID:(NSString *)masterSecretID 208 | walletHandle:(nonnull NSNumber *)walletHandle 209 | resolver:(RCTPromiseResolveBlock)resolve 210 | rejecter:(RCTPromiseRejectBlock)reject) 211 | 212 | RCT_EXTERN_METHOD(proverStoreCredential: (NSString *)credJson 213 | credID:(NSString *)credID 214 | credReqMetadataJSON:(NSString *)credReqMetadataJSON 215 | credDefJSON:(NSString *)credDefJSON 216 | revRegDefJSON:(NSString *)revRegDefJSON walletHandle:(nonnull NSNumber *)walletHandle 217 | resolver:(RCTPromiseResolveBlock)resolve 218 | rejecter:(RCTPromiseRejectBlock)reject) 219 | 220 | RCT_EXTERN_METHOD(proverGetCredentials: (NSString *)filter walletHandle:(nonnull NSNumber *)walletHandle 221 | resolver:(RCTPromiseResolveBlock)resolve 222 | rejecter:(RCTPromiseRejectBlock)reject) 223 | 224 | RCT_EXTERN_METHOD(proverGetCredential: (NSString *)credId walletHandle:(nonnull NSNumber *)walletHandle 225 | resolver:(RCTPromiseResolveBlock)resolve 226 | rejecter:(RCTPromiseRejectBlock)reject) 227 | 228 | RCT_EXTERN_METHOD(proverGetCredentialsForProofReq: (NSString *)proofReqJSON walletHandle:(nonnull NSNumber *)walletHandle 229 | resolver:(RCTPromiseResolveBlock)resolve 230 | rejecter:(RCTPromiseRejectBlock)reject) 231 | 232 | RCT_EXTERN_METHOD(proverSearchCredentialsForProofReq: (nonnull NSNumber *)walletHandle 233 | proofReqJSON: (NSString *)proofReqJSON 234 | extraQueryJSON: (NSString *)extraQueryJSON 235 | resolver:(RCTPromiseResolveBlock)resolve 236 | rejecter:(RCTPromiseRejectBlock)reject 237 | ) 238 | 239 | RCT_EXTERN_METHOD(proverFetchCredentialsForProofReq: (nonnull NSNumber *)searchHandle 240 | itemReferent: (NSString *)itemReferent 241 | count: (nonnull NSNumber *)count 242 | resolver:(RCTPromiseResolveBlock)resolve 243 | rejecter:(RCTPromiseRejectBlock)reject 244 | ) 245 | 246 | RCT_EXTERN_METHOD(proverCloseCredentialsSearchForProofReq: (nonnull NSNumber *)searchHandle 247 | resolver:(RCTPromiseResolveBlock)resolve 248 | rejecter:(RCTPromiseRejectBlock)reject 249 | ) 250 | 251 | RCT_EXTERN_METHOD(proverCreateProofForRequest: (NSString *)proofReqJSON 252 | requestedCredentialsJSON:(NSString *)requestedCredentialsJSON 253 | masterSecretID:(NSString *)masterSecretID 254 | schemasJSON:(NSString *)schemasJSON 255 | credentialDefsJSON:(NSString *)credentialDefsJSON 256 | revocStatesJSON:(NSString *)revocStatesJSON 257 | walletHandle:(nonnull NSNumber *)walletHandle 258 | resolver:(RCTPromiseResolveBlock)resolve 259 | rejecter:(RCTPromiseRejectBlock)reject) 260 | 261 | RCT_EXTERN_METHOD(verifierVerifyProof: (NSString *)proofReqJSON 262 | proofJSON:(NSString *)proofJSON 263 | schemasJSON:(NSString *)schemasJSON 264 | credentialDefsJSON:(NSString *)credentialDefsJSON 265 | revocRegDefsJSON:(NSString *)revocRegDefsJSON 266 | revocRegsJSON:(NSString *)revocRegsJSON 267 | resolver:(RCTPromiseResolveBlock)resolve 268 | rejecter:(RCTPromiseRejectBlock)reject) 269 | 270 | // non_secrets 271 | RCT_EXTERN_METHOD(addWalletRecord: (nonnull NSNumber *)wh 272 | type: (NSString *)type 273 | id: (NSString *)id 274 | value: (NSString *)value 275 | tags: (NSString *)tags 276 | resolver:(RCTPromiseResolveBlock)resolve 277 | rejecter:(RCTPromiseRejectBlock)reject 278 | ) 279 | 280 | RCT_EXTERN_METHOD(updateWalletRecordValue: (nonnull NSNumber *)wh 281 | type: (NSString *)type 282 | id: (NSString *)id 283 | value: (NSString *)value 284 | resolver:(RCTPromiseResolveBlock)resolve 285 | rejecter:(RCTPromiseRejectBlock)reject 286 | ) 287 | 288 | RCT_EXTERN_METHOD(updateWalletRecordTags: (nonnull NSNumber *)wh 289 | type: (NSString *)type 290 | id: (NSString *)id 291 | tags: (NSString *)tags 292 | resolver:(RCTPromiseResolveBlock)resolve 293 | rejecter:(RCTPromiseRejectBlock)reject 294 | ) 295 | 296 | RCT_EXTERN_METHOD(addWalletRecordTags: (nonnull NSNumber *)wh 297 | type: (NSString *)type 298 | id: (NSString *)id 299 | tags: (NSString *)tags 300 | resolver:(RCTPromiseResolveBlock)resolve 301 | rejecter:(RCTPromiseRejectBlock)reject 302 | ) 303 | 304 | RCT_EXTERN_METHOD(deleteWalletRecordTags: (nonnull NSNumber *)wh 305 | type: (NSString *)type 306 | id: (NSString *)id 307 | tags: (NSString *)tags 308 | resolver:(RCTPromiseResolveBlock)resolve 309 | rejecter:(RCTPromiseRejectBlock)reject 310 | ) 311 | 312 | RCT_EXTERN_METHOD(deleteWalletRecord: (nonnull NSNumber *)wh 313 | type: (NSString *)type 314 | id: (NSString *)id 315 | resolver:(RCTPromiseResolveBlock)resolve 316 | rejecter:(RCTPromiseRejectBlock)reject 317 | ) 318 | 319 | RCT_EXTERN_METHOD(getWalletRecord: (nonnull NSNumber *)wh 320 | type: (NSString *)type 321 | id: (NSString *)id 322 | options: (NSString *)options 323 | resolver:(RCTPromiseResolveBlock)resolve 324 | rejecter:(RCTPromiseRejectBlock)reject 325 | ) 326 | 327 | RCT_EXTERN_METHOD(openWalletSearch: (nonnull NSNumber *)wh 328 | type: (NSString *)type 329 | query: (NSString *)query 330 | options: (NSString *)options 331 | resolver:(RCTPromiseResolveBlock)resolve 332 | rejecter:(RCTPromiseRejectBlock)reject 333 | ) 334 | 335 | RCT_EXTERN_METHOD(fetchWalletSearchNextRecords: (nonnull NSNumber *)wh 336 | sh: (nonnull NSNumber *)sh 337 | count: (nonnull NSNumber *)count 338 | resolver:(RCTPromiseResolveBlock)resolve 339 | rejecter:(RCTPromiseRejectBlock)reject 340 | ) 341 | 342 | RCT_EXTERN_METHOD(closeWalletSearch: (nonnull NSNumber *)sh 343 | resolver:(RCTPromiseResolveBlock)resolve 344 | rejecter:(RCTPromiseRejectBlock)reject 345 | ) 346 | 347 | @end 348 | -------------------------------------------------------------------------------- /ios/IndySdk.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2019 ABSA Group Limited 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | import Foundation 18 | import Indy 19 | 20 | struct WalletConfig: Codable { 21 | var id: String 22 | } 23 | 24 | @objc(IndySdk) 25 | class IndySdk : NSObject { 26 | 27 | private static var walletIdHandleDict: [String: Int32] = [:] 28 | private static var poolIdHandleDict: [String: Int32] = [:] 29 | 30 | @objc func sampleMethod(_ stringArgument: String, numberArgument: NSNumber, 31 | resolver resolve: @escaping RCTPromiseResolveBlock, 32 | rejecter reject: @escaping RCTPromiseRejectBlock) { 33 | resolve("result") 34 | } 35 | 36 | @objc func createWallet(_ config: String, credentials: String, 37 | resolver resolve: @escaping RCTPromiseResolveBlock, 38 | rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 39 | let indyWallet = IndyWallet() 40 | 41 | indyWallet.createWallet(withConfig: config, credentials: credentials, completion: completion(resolve, reject)) 42 | } 43 | 44 | @objc func openWallet(_ config: String, credentials: String, 45 | resolver resolve: @escaping RCTPromiseResolveBlock, 46 | rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 47 | 48 | // Test if a wallet handle is already available 49 | 50 | let decoder = JSONDecoder() 51 | guard let configJSON = config.data(using: .utf8), 52 | let walletConfig: WalletConfig = try? decoder.decode(WalletConfig.self, from: configJSON) 53 | else { 54 | reject("-1000", "Non parseable config: \(config)", NSError(domain: "Indy", code: -1000, userInfo: nil)) 55 | return; 56 | } 57 | 58 | // If wallet is already opened, return the wallet handle 59 | if let walletHandle = IndySdk.walletIdHandleDict[walletConfig.id] { 60 | resolve(walletHandle) 61 | } 62 | else{ 63 | let indyWallet = IndyWallet() 64 | indyWallet.open(withConfig: config, credentials: credentials, completion: completionWithWalletHandle(resolve, reject, walletConfig.id)) 65 | } 66 | } 67 | 68 | @objc func closeWallet(_ walletHandle: NSNumber, 69 | resolver resolve: @escaping RCTPromiseResolveBlock, 70 | rejecter reject: @escaping RCTPromiseRejectBlock) { 71 | let whNumber:Int32 = Int32(truncating: walletHandle) 72 | let indyWallet = IndyWallet() 73 | 74 | // Remove wallet handle map 75 | for (walletId, walletHandle) in IndySdk.walletIdHandleDict { 76 | if walletHandle == whNumber { 77 | IndySdk.walletIdHandleDict.removeValue(forKey: walletId) 78 | } 79 | } 80 | 81 | indyWallet.close(withHandle: whNumber, completion: completion(resolve, reject)) 82 | } 83 | 84 | @objc func deleteWallet(_ config: String, credentials: String, 85 | resolver resolve: @escaping RCTPromiseResolveBlock, 86 | rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 87 | let indyWallet = IndyWallet() 88 | 89 | indyWallet.delete(withConfig: config, credentials: credentials, completion: completion(resolve, reject)) 90 | } 91 | 92 | @objc func exportWallet(_ walletHandle: NSNumber, exportConfig: String, 93 | resolver resolve: @escaping RCTPromiseResolveBlock, 94 | rejecter reject: @escaping RCTPromiseRejectBlock) { 95 | let whNumber:Int32 = Int32(truncating: walletHandle) 96 | let indyWallet = IndyWallet() 97 | 98 | indyWallet.export(withHandle: whNumber, exportConfigJson: exportConfig, completion: completion(resolve, reject)) 99 | } 100 | 101 | @objc func importWallet(_ config: String, credentials: String, importConfig: String, 102 | resolver resolve: @escaping RCTPromiseResolveBlock, 103 | rejecter reject: @escaping RCTPromiseRejectBlock) { 104 | let indyWallet = IndyWallet() 105 | indyWallet.import(withConfig: config, credentials: credentials, importConfigJson: importConfig, completion: completion(resolve, reject)) 106 | } 107 | 108 | // did 109 | 110 | @objc func createAndStoreMyDid(_ didJson: String!, walletHandle: NSNumber, 111 | resolver resolve: @escaping RCTPromiseResolveBlock, 112 | rejecter reject: @escaping RCTPromiseRejectBlock) { 113 | let whNumber:Int32 = Int32(truncating: walletHandle) 114 | 115 | func completion(error: Error?, did: String?, verkey: String?) -> Void { 116 | let code = (error! as NSError).code 117 | if code != 0 { 118 | reject("\(code)", createJsonError(error!, code), error) 119 | } else { 120 | resolve([did, verkey]) 121 | } 122 | } 123 | 124 | IndyDid.createAndStoreMyDid(didJson, walletHandle: whNumber, completion: completion) 125 | } 126 | 127 | @objc func keyForDid(_ did: String!, poolHandle: NSNumber, walletHandle: NSNumber, 128 | resolver resolve: @escaping RCTPromiseResolveBlock, 129 | rejecter reject: @escaping RCTPromiseRejectBlock) { 130 | let phNumber:Int32 = Int32(truncating:poolHandle) 131 | let whNumber:Int32 = Int32(truncating:walletHandle) 132 | 133 | IndyDid.key(forDid: did, poolHandle: phNumber, walletHandle: whNumber, completion: completionWithVerkey(resolve, reject)) 134 | } 135 | 136 | @objc func keyForLocalDid(_ did: String!, walletHandle: NSNumber, 137 | resolver resolve: @escaping RCTPromiseResolveBlock, 138 | rejecter reject: @escaping RCTPromiseRejectBlock) { 139 | let whNumber:Int32 = Int32(truncating:walletHandle) 140 | 141 | IndyDid.key(forLocalDid: did, walletHandle: whNumber, completion: completionWithVerkey(resolve, reject)) 142 | } 143 | 144 | @objc func storeTheirDid(_ identityJSON: String!, walletHandle: NSNumber, 145 | resolver resolve: @escaping RCTPromiseResolveBlock, 146 | rejecter reject: @escaping RCTPromiseRejectBlock) { 147 | let whNumber:Int32 = Int32(truncating:walletHandle) 148 | 149 | IndyDid.storeTheirDid(identityJSON, walletHandle: whNumber, completion: completion(resolve, reject)) 150 | } 151 | 152 | @objc func createPairwise(_ theirDid: String!, myDid: String!, metadata: String!, walletHandle: NSNumber, 153 | resolver resolve: @escaping RCTPromiseResolveBlock, 154 | rejecter reject: @escaping RCTPromiseRejectBlock) { 155 | let whNumber:Int32 = Int32(truncating:walletHandle) 156 | 157 | IndyPairwise.createPairwise(forTheirDid: theirDid, myDid: myDid, metadata: metadata, walletHandle: whNumber, completion: completion(resolve, reject)) 158 | } 159 | 160 | @objc func getPairwise(_ theirDid: String!, walletHandle: NSNumber, 161 | resolver resolve: @escaping RCTPromiseResolveBlock, 162 | rejecter reject: @escaping RCTPromiseRejectBlock) { 163 | let whNumber:Int32 = Int32(truncating:walletHandle) 164 | IndyPairwise.getForTheirDid(theirDid, walletHandle: whNumber, completion: completionWithPairwiseInfo(resolve, reject)) 165 | } 166 | 167 | // crypto 168 | 169 | @objc func cryptoAnonCrypt(_ message: String, theirKey: String!, 170 | resolver resolve: @escaping RCTPromiseResolveBlock, 171 | rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 172 | let messageData = message.data(using: .utf8) 173 | IndyCrypto.anonCrypt(messageData, theirKey: theirKey, completion: completionWithData(resolve, reject)) 174 | } 175 | 176 | @objc func cryptoAnonDecrypt(_ encryptedMessage: Array, myKey: String!, walletHandle: NSNumber, 177 | resolver resolve: @escaping RCTPromiseResolveBlock, 178 | rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 179 | let whNumber:Int32 = Int32(truncating:walletHandle) 180 | let encryptedMessageData = Data(bytes: encryptedMessage) 181 | IndyCrypto.anonDecrypt(encryptedMessageData, myKey: myKey, walletHandle: whNumber, completion: completionWithData(resolve, reject)) 182 | } 183 | 184 | @objc func cryptoAuthCrypt(_ message: String, myKey: String!, theirKey: String!, walletHandle: NSNumber, 185 | resolver resolve: @escaping RCTPromiseResolveBlock, 186 | rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 187 | let whNumber:Int32 = Int32(truncating:walletHandle) 188 | IndyCrypto.authCrypt(message.data(using: .utf8), myKey: myKey, theirKey: theirKey, walletHandle: whNumber, completion: completionWithData(resolve, reject)) 189 | } 190 | 191 | @objc func cryptoAuthDecrypt(_ encryptedMessage: Array, myKey: String!, walletHandle: NSNumber, 192 | resolver resolve: @escaping RCTPromiseResolveBlock, 193 | rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 194 | let whNumber:Int32 = Int32(truncating:walletHandle) 195 | 196 | IndyCrypto.authDecrypt(Data(bytes: encryptedMessage), myKey: myKey, walletHandle: whNumber, completion: completionWithTheirKeyAndData(resolve, reject)) 197 | } 198 | 199 | @objc func cryptoSign(_ wh: NSNumber, signerVk: String, message: Array, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 200 | let whNumber = Int32(truncating: wh) 201 | let messageData = Data(message) 202 | IndyCrypto.signMessage(messageData, key: signerVk, walletHandle: whNumber, completion: completionWithData(resolve, reject)) 203 | } 204 | 205 | @objc func cryptoVerify(_ signerVk: String, message: Array, signature: Array, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 206 | let messageData = Data(message) 207 | let signatureData = Data(signature) 208 | IndyCrypto.verifySignature(signatureData, forMessage: messageData, key: signerVk, completion: completionWithBool(resolve, reject)) 209 | } 210 | 211 | @objc func packMessage(_ wh: NSNumber, message: Array, receiverKeys: String, senderVk: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 212 | let whNumber = Int32(truncating: wh) 213 | let messageData = Data(message) 214 | IndyCrypto.packMessage(messageData, receivers: receiverKeys, sender: senderVk, walletHandle: whNumber, completion: completionWithData(resolve, reject)) 215 | } 216 | 217 | @objc func unpackMessage(_ wh: NSNumber, jwe: Array, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 218 | let whNumber = Int32(truncating: wh) 219 | let jweData = Data(jwe) 220 | IndyCrypto.unpackMessage(jweData, walletHandle: whNumber, completion: completionWithData(resolve, reject)) 221 | } 222 | 223 | 224 | // pool 225 | 226 | @objc func setProtocolVersion(_ protocolVersion: NSNumber, 227 | resolver resolve: @escaping RCTPromiseResolveBlock, 228 | rejecter reject: @escaping RCTPromiseRejectBlock) { 229 | IndyPool.setProtocolVersion(protocolVersion, completion: completion(resolve, reject)); 230 | } 231 | 232 | @objc func createPoolLedgerConfig(_ name: String, poolConfig: String, 233 | resolver resolve: @escaping RCTPromiseResolveBlock, 234 | rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 235 | IndyPool.createPoolLedgerConfig(withPoolName: name, poolConfig: poolConfig, completion: completion(resolve, reject)) 236 | } 237 | 238 | @objc func openLedger(_ name: String, poolConfig: String?, 239 | resolver resolve: @escaping RCTPromiseResolveBlock, 240 | rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 241 | if let poolHandle = IndySdk.poolIdHandleDict[name] { 242 | resolve(poolHandle) 243 | } 244 | else{ 245 | IndyPool.openLedger(withName: name, poolConfig: poolConfig, completion: completionWithPoolHandle(resolve, reject, name)) 246 | } 247 | 248 | } 249 | 250 | @objc func closePoolLedger(_ poolHandle: NSNumber, 251 | resolver resolve: @escaping RCTPromiseResolveBlock, 252 | rejecter reject: @escaping RCTPromiseRejectBlock) { 253 | let phNumber:Int32 = Int32(truncating: poolHandle) 254 | 255 | let handleDict = IndySdk.poolIdHandleDict.filter { $0.value == poolHandle.intValue } 256 | // Remove value for name 257 | if let name = handleDict.first?.key { 258 | IndySdk.poolIdHandleDict.removeValue(forKey: name) 259 | } 260 | 261 | IndyPool.closeLedger(withHandle: phNumber, completion: completion(resolve, reject)) 262 | } 263 | 264 | // ledger 265 | 266 | @objc func submitRequest(_ requestJSON: String, poolHandle: NSNumber, 267 | resolver resolve: @escaping RCTPromiseResolveBlock, 268 | rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 269 | let phNumber:Int32 = Int32(truncating:poolHandle) 270 | IndyLedger.submitRequest(requestJSON, poolHandle: phNumber, completion: completionWithString(resolve, reject)) 271 | } 272 | 273 | @objc func buildGetSchemaRequest(_ submitterDid: String, id: String, 274 | resolver resolve: @escaping RCTPromiseResolveBlock, 275 | rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 276 | IndyLedger.buildGetSchemaRequest( 277 | withSubmitterDid: !submitterDid.isEmpty ? submitterDid : nil, 278 | id: id, 279 | completion: completionWithString(resolve, reject) 280 | ) 281 | } 282 | 283 | @objc func parseGetSchemaResponse(_ getSchemaResponse: String, 284 | resolver resolve: @escaping RCTPromiseResolveBlock, 285 | rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 286 | IndyLedger.parseGetSchemaResponse(getSchemaResponse, completion: completionWithStringPair(resolve, reject)) 287 | } 288 | 289 | @objc func buildGetCredDefRequest(_ submitterDid: String, id: String, 290 | resolver resolve: @escaping RCTPromiseResolveBlock, 291 | rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 292 | IndyLedger.buildGetCredDefRequest( 293 | withSubmitterDid: !submitterDid.isEmpty ? submitterDid : nil, 294 | id: id, 295 | completion: completionWithString(resolve, reject) 296 | ) 297 | } 298 | 299 | @objc func parseGetCredDefResponse(_ getCredDefResponse: String, 300 | resolver resolve: @escaping RCTPromiseResolveBlock, 301 | rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 302 | IndyLedger.parseGetCredDefResponse(getCredDefResponse, completion: completionWithStringPair(resolve, reject)) 303 | } 304 | 305 | @objc func buildGetAttribRequest(_ submitterDid: String?, 306 | targetDid: String, 307 | raw: String?, 308 | hash: String?, 309 | enc: String?, 310 | resolver resolve: @escaping RCTPromiseResolveBlock, 311 | rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 312 | IndyLedger.buildGetAttribRequest(withSubmitterDid: submitterDid, targetDID: targetDid, raw: raw, hash: hash, enc: enc, completion: completionWithString(resolve, reject)) 313 | } 314 | 315 | @objc func buildGetNymRequest(_ submitterDid: String?, 316 | targetDid: String, 317 | resolver resolve: @escaping RCTPromiseResolveBlock, 318 | rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 319 | IndyLedger.buildGetNymRequest(withSubmitterDid: submitterDid, targetDID: targetDid, completion: completionWithString(resolve, reject)) 320 | } 321 | 322 | @objc func parseGetNymResponse(_ response: String, 323 | resolver resolve: @escaping RCTPromiseResolveBlock, 324 | rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 325 | IndyLedger.parseGetNymResponse(response, completion: completionWithString(resolve, reject)) 326 | } 327 | 328 | 329 | 330 | // anoncreds 331 | 332 | @objc func proverCreateMasterSecret(_ masterSecretId: String, walletHandle: NSNumber, 333 | resolver resolve: @escaping RCTPromiseResolveBlock, 334 | rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 335 | let whNumber:Int32 = Int32(truncating:walletHandle) 336 | 337 | IndyAnoncreds.proverCreateMasterSecret( 338 | !masterSecretId.isEmpty ? masterSecretId : nil, 339 | walletHandle: whNumber, 340 | completion: completionWithString(resolve, reject) 341 | ) 342 | } 343 | 344 | @objc func proverCreateCredentialReq(_ credOfferJSON: String, credentialDefJSON: String, proverDID: String, masterSecretID: String, walletHandle: NSNumber, 345 | resolver resolve: @escaping RCTPromiseResolveBlock, 346 | rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 347 | let whNumber:Int32 = Int32(truncating:walletHandle) 348 | IndyAnoncreds.proverCreateCredentialReq( 349 | forCredentialOffer: credOfferJSON, 350 | credentialDefJSON: credentialDefJSON, 351 | proverDID: proverDID, 352 | masterSecretID: masterSecretID, 353 | walletHandle: whNumber, 354 | completion: completionWithStringPair(resolve, reject) 355 | ) 356 | } 357 | 358 | @objc func proverStoreCredential(_ credJson: String, credID: String, credReqMetadataJSON: String, credDefJSON: String, revRegDefJSON: String, walletHandle: NSNumber, 359 | resolver resolve: @escaping RCTPromiseResolveBlock, 360 | rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 361 | let whNumber:Int32 = Int32(truncating:walletHandle) 362 | IndyAnoncreds.proverStoreCredential( 363 | credJson, 364 | credID: !credID.isEmpty ? credID : nil, 365 | credReqMetadataJSON: credReqMetadataJSON, 366 | credDefJSON: credDefJSON, 367 | revRegDefJSON: !revRegDefJSON.isEmpty ? revRegDefJSON : nil, 368 | walletHandle: whNumber, completion: completionWithString(resolve, reject)) 369 | } 370 | 371 | @objc func proverGetCredentials(_ filterJSON: String, walletHandle: NSNumber, 372 | resolver resolve: @escaping RCTPromiseResolveBlock, 373 | rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 374 | let whNumber:Int32 = Int32(truncating:walletHandle) 375 | IndyAnoncreds.proverGetCredentials(forFilter: filterJSON, walletHandle: whNumber, completion: completionWithString(resolve, reject)) 376 | } 377 | 378 | @objc func proverGetCredential(_ credId: String, walletHandle: NSNumber, 379 | resolver resolve: @escaping RCTPromiseResolveBlock, 380 | rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 381 | let whNumber:Int32 = Int32(truncating:walletHandle) 382 | IndyAnoncreds.proverGetCredential(withId: credId, walletHandle: whNumber, completion: completionWithString(resolve, reject)) 383 | } 384 | 385 | @objc func proverGetCredentialsForProofReq(_ proofReqJSON: String, walletHandle: NSNumber, 386 | resolver resolve: @escaping RCTPromiseResolveBlock, 387 | rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 388 | let whNumber:Int32 = Int32(truncating:walletHandle) 389 | IndyAnoncreds.proverGetCredentials(forProofReq: proofReqJSON, walletHandle: whNumber, completion: completionWithString(resolve, reject)) 390 | } 391 | 392 | @objc func proverSearchCredentialsForProofReq(_ walletHandle: NSNumber,proofReqJSON: String, extraQueryJSON: String, 393 | resolver resolve: @escaping RCTPromiseResolveBlock, 394 | rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 395 | let whNumber:Int32 = Int32(truncating:walletHandle) 396 | IndyAnoncreds.proverSearchCredentials(forProofRequest: proofReqJSON, extraQueryJSON: extraQueryJSON, walletHandle:whNumber, completion: completionWithIndyHandle(resolve, reject)) 397 | } 398 | 399 | @objc func proverFetchCredentialsForProofReq(_ searchHandle:NSNumber, itemReferent: String, count: NSNumber, 400 | resolver resolve: @escaping RCTPromiseResolveBlock, 401 | rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 402 | let shNumber:Int32 = Int32(truncating: searchHandle) 403 | IndyAnoncreds.proverFetchCredentials(forProofReqItemReferent: itemReferent, searchHandle: shNumber, count:count, completion: completionWithString(resolve, reject)) 404 | } 405 | 406 | @objc func proverCloseCredentialsSearchForProofReq(_ searchHandle:NSNumber, 407 | resolver resolve: @escaping RCTPromiseResolveBlock, 408 | rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 409 | let shNumber:Int32 = Int32(truncating: searchHandle) 410 | IndyAnoncreds.proverCloseCredentialsSearchForProofReq(withHandle: shNumber, completion: completion(resolve, reject)) 411 | } 412 | 413 | @objc func proverCreateProofForRequest(_ proofReqJSON: String, requestedCredentialsJSON: String, masterSecretID: String, schemasJSON: String, credentialDefsJSON: String, revocStatesJSON: String, walletHandle: NSNumber, 414 | resolver resolve: @escaping RCTPromiseResolveBlock, 415 | rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 416 | let whNumber:Int32 = Int32(truncating:walletHandle) 417 | IndyAnoncreds.proverCreateProof( 418 | forRequest: proofReqJSON, 419 | requestedCredentialsJSON: requestedCredentialsJSON, 420 | masterSecretID: masterSecretID, 421 | schemasJSON: schemasJSON, 422 | credentialDefsJSON: credentialDefsJSON, 423 | revocStatesJSON: revocStatesJSON, 424 | walletHandle: whNumber, 425 | completion: completionWithString(resolve, reject) 426 | ) 427 | } 428 | 429 | @objc func verifierVerifyProof(_ proofReqJSON: String, proofJSON: String, schemasJSON: String, credentialDefsJSON: String, revocRegDefsJSON: String, revocRegsJSON: String, 430 | resolver resolve: @escaping RCTPromiseResolveBlock, 431 | rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 432 | IndyAnoncreds.verifierVerifyProofRequest( 433 | proofReqJSON, 434 | proofJSON: proofJSON, 435 | schemasJSON: schemasJSON, 436 | credentialDefsJSON: credentialDefsJSON, 437 | revocRegDefsJSON: revocRegDefsJSON, 438 | revocRegsJSON: revocRegsJSON, 439 | completion: completionWithBool(resolve, reject) 440 | ) 441 | } 442 | 443 | // non_secret 444 | 445 | @objc func addWalletRecord(_ wh: NSNumber, type: String, id: String, value: String, tags: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 446 | let whNumber:Int32 = Int32(truncating: wh) 447 | IndyNonSecrets.addRecord(inWallet: whNumber, type: type, id: id, value: value, tagsJson: tags, completion: completion(resolve, reject)) 448 | } 449 | 450 | @objc func updateWalletRecordValue(_ wh: NSNumber, type: String, id: String, value: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 451 | let whNumber:Int32 = Int32(truncating: wh) 452 | IndyNonSecrets.updateRecordValue(inWallet: whNumber, type: type, id: id, value: value, completion: completion(resolve, reject)) 453 | } 454 | 455 | @objc func updateWalletRecordTags(_ wh: NSNumber, type: String, id: String, tags: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 456 | let whNumber:Int32 = Int32(truncating: wh) 457 | IndyNonSecrets.updateRecordTags(inWallet: whNumber, type: type, id: id, tagsJson: tags, completion: completion(resolve, reject)) 458 | } 459 | 460 | @objc func addWalletRecordTags(_ wh: NSNumber, type: String, id: String, tags: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 461 | let whNumber:Int32 = Int32(truncating: wh) 462 | IndyNonSecrets.addRecordTags(inWallet: whNumber, type: type, id: id, tagsJson: tags, completion: completion(resolve, reject)) 463 | } 464 | 465 | @objc func deleteWalletRecordTags(_ wh: NSNumber, type: String, id: String, tags: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 466 | let whNumber:Int32 = Int32(truncating: wh) 467 | IndyNonSecrets.deleteRecordTags(inWallet: whNumber, type: type, id: id, tagsNames: tags, completion: completion(resolve, reject)) 468 | } 469 | 470 | @objc func deleteWalletRecord(_ wh: NSNumber, type: String, id: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 471 | let whNumber:Int32 = Int32(truncating: wh) 472 | IndyNonSecrets.deleteRecord(inWallet: whNumber, type: type, id: id, completion: completion(resolve, reject)) 473 | } 474 | 475 | @objc func getWalletRecord(_ wh: NSNumber, type: String, id: String, options: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 476 | let whNumber:Int32 = Int32(truncating: wh) 477 | IndyNonSecrets.getRecordFromWallet(whNumber, type: type, id: id, optionsJson: options, completion: completionWithString(resolve, reject)) 478 | } 479 | 480 | @objc func openWalletSearch(_ wh: NSNumber, type: String, query: String, options: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 481 | let whNumber:Int32 = Int32(truncating: wh) 482 | IndyNonSecrets.openSearch(inWallet: whNumber, type: type, queryJson: query, optionsJson: options, completion: completionWithIndyHandle(resolve, reject)) 483 | } 484 | 485 | @objc func fetchWalletSearchNextRecords(_ wh: NSNumber, sh: NSNumber, count: NSNumber, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 486 | let whNumber:Int32 = Int32(truncating: wh) 487 | let shNumber:Int32 = Int32(truncating: sh) 488 | IndyNonSecrets.fetchNextRecords(fromSearch: shNumber, walletHandle: whNumber, count: count, completion: completionWithString(resolve, reject)) 489 | } 490 | 491 | @objc func closeWalletSearch(_ sh: NSNumber, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { 492 | let shNumber:Int32 = Int32(truncating: sh) 493 | IndyNonSecrets.closeSearch(withHandle: shNumber, completion: completion(resolve, reject)) 494 | } 495 | 496 | // completion functions 497 | 498 | func completion(_ resolve: @escaping RCTPromiseResolveBlock, 499 | _ reject: @escaping RCTPromiseRejectBlock) -> (_ error: Error?) -> Void { 500 | func completion(error: Error?) -> Void { 501 | let code = (error! as NSError).code 502 | if code != 0 { 503 | reject("\(code)", createJsonError(error!, code), error) 504 | } else { 505 | resolve(nil) 506 | } 507 | } 508 | 509 | return completion 510 | } 511 | 512 | func completionWithWalletHandle(_ resolve: @escaping RCTPromiseResolveBlock, 513 | _ reject: @escaping RCTPromiseRejectBlock, _ walletId: String) -> (_ error: Error?, _ wh: IndyHandle) -> Void { 514 | func completion(error: Error?, wh: IndyHandle) -> Void { 515 | let code = (error! as NSError).code 516 | if code != 0 { 517 | reject("\(code)", createJsonError(error!, code), error) 518 | } else { 519 | IndySdk.walletIdHandleDict[walletId] = wh 520 | resolve(wh) 521 | } 522 | } 523 | 524 | return completion 525 | 526 | } 527 | 528 | func completionWithPoolHandle(_ resolve: @escaping RCTPromiseResolveBlock, 529 | _ reject: @escaping RCTPromiseRejectBlock, 530 | _ poolName: String) -> (_ error: Error?, _ wh: IndyHandle) -> Void { 531 | func completion(error: Error?, ih: IndyHandle) -> Void { 532 | let code = (error! as NSError).code 533 | if code != 0 { 534 | reject("\(code)", createJsonError(error!, code), error) 535 | } else { 536 | IndySdk.poolIdHandleDict[poolName] = ih 537 | resolve(ih) 538 | } 539 | } 540 | 541 | return completion 542 | } 543 | 544 | func completionWithIndyHandle(_ resolve: @escaping RCTPromiseResolveBlock, 545 | _ reject: @escaping RCTPromiseRejectBlock) -> (_ error: Error?, _ wh: IndyHandle) -> Void { 546 | func completion(error: Error?, ih: IndyHandle) -> Void { 547 | let code = (error! as NSError).code 548 | if code != 0 { 549 | reject("\(code)", createJsonError(error!, code), error) 550 | } else { 551 | resolve(ih) 552 | } 553 | } 554 | 555 | return completion 556 | } 557 | 558 | func completionWithVerkey(_ resolve: @escaping RCTPromiseResolveBlock, 559 | _ reject: @escaping RCTPromiseRejectBlock) -> (_ error: Error?, _ verkey: String?) -> Void { 560 | func completion(error: Error?, verkey: String?) -> Void { 561 | let code = (error! as NSError).code 562 | if code != 0 { 563 | reject("\(code)", createJsonError(error!, code), error) 564 | } else { 565 | resolve(verkey) 566 | } 567 | } 568 | 569 | return completion 570 | } 571 | 572 | func completionWithPairwiseInfo(_ resolve: @escaping RCTPromiseResolveBlock, 573 | _ reject: @escaping RCTPromiseRejectBlock) -> (_ error: Error?, _ pairwiseInfo: String?) -> Void { 574 | func completion(error: Error?, pairwiseInfo: String?) -> Void { 575 | let code = (error! as NSError).code 576 | if code != 0 { 577 | reject("\(code)", createJsonError(error!, code), error) 578 | } else { 579 | resolve(pairwiseInfo) 580 | } 581 | } 582 | 583 | return completion 584 | } 585 | 586 | func completionWithData(_ resolve: @escaping RCTPromiseResolveBlock, 587 | _ reject: @escaping RCTPromiseRejectBlock) -> (_ error: Error?, _ data: Data?) -> Void { 588 | func completion(error: Error?, data: Data?) -> Void { 589 | let code = (error! as NSError).code 590 | if code != 0 { 591 | reject("\(code)", createJsonError(error!, code), error) 592 | } else { 593 | resolve(NSArray(array: [UInt8](data!))) 594 | } 595 | } 596 | 597 | return completion 598 | } 599 | 600 | func completionWithTheirKeyAndData(_ resolve: @escaping RCTPromiseResolveBlock, 601 | _ reject: @escaping RCTPromiseRejectBlock) -> (_ error: Error?, _ theirKey: String?, _ data: Data?) -> Void { 602 | func completion(error: Error?, theirKey: String?, data: Data?) -> Void { 603 | let code = (error! as NSError).code 604 | if code != 0 { 605 | reject("\(code)", createJsonError(error!, code), error) 606 | } else { 607 | resolve([theirKey!, NSArray(array: [UInt8](data!))]) 608 | } 609 | } 610 | 611 | return completion 612 | } 613 | 614 | func completionWithString(_ resolve: @escaping RCTPromiseResolveBlock, 615 | _ reject: @escaping RCTPromiseRejectBlock) -> (_ error: Error?, _ result: String?) -> Void { 616 | func completion(error: Error?, result: String?) -> Void { 617 | let code = (error! as NSError).code 618 | if code != 0 { 619 | reject("\(code)", createJsonError(error!, code), error) 620 | } else { 621 | resolve(result) 622 | } 623 | } 624 | 625 | return completion 626 | } 627 | 628 | func completionWithBool(_ resolve: @escaping RCTPromiseResolveBlock, 629 | _ reject: @escaping RCTPromiseRejectBlock) -> (_ error: Error?, _ result: Bool) -> Void { 630 | func completion(error: Error?, result: Bool) -> Void { 631 | let code = (error! as NSError).code 632 | if code != 0 { 633 | reject("\(code)", createJsonError(error!, code), error) 634 | } else { 635 | resolve(result) 636 | } 637 | } 638 | 639 | return completion 640 | } 641 | 642 | func completionWithStringPair(_ resolve: @escaping RCTPromiseResolveBlock, 643 | _ reject: @escaping RCTPromiseRejectBlock) -> (_ error: Error?, _ string1: String?, _ string2: String?) -> Void { 644 | func completion(error: Error?, string1: String?, string2: String?) -> Void { 645 | let code = (error! as NSError).code 646 | if code != 0 { 647 | reject("\(code)", createJsonError(error!, code), error) 648 | } else { 649 | resolve([string1, string2]) 650 | } 651 | } 652 | 653 | return completion 654 | } 655 | 656 | struct ErrorMessage: Codable { 657 | var message: String 658 | var indyCode: Int 659 | } 660 | 661 | func createJsonError(_ error: Error, _ code: Int) -> String! { 662 | let jsonEncoder = JSONEncoder() 663 | do { 664 | let message = "IndySdk: \(String(describing: error))" 665 | let jsonData = try jsonEncoder.encode(ErrorMessage(message: message, indyCode: code)) 666 | return String(data: jsonData, encoding: .utf8) 667 | } catch { 668 | // This code can perhaps replace implementation above 669 | return "{\"message\": \"IndySdk: \(String(describing: error))\"}" 670 | } 671 | } 672 | 673 | @objc 674 | static func requiresMainQueueSetup() -> Bool { 675 | return false 676 | } 677 | } 678 | -------------------------------------------------------------------------------- /ios/IndySdk.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | AD7073A323DF0AF000926D62 /* IndySdk.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD7073A223DF0AF000926D62 /* IndySdk.swift */; }; 11 | B3E7B58A1CC2AC0600A0062D /* IndySdk.m in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* IndySdk.m */; }; 12 | /* End PBXBuildFile section */ 13 | 14 | /* Begin PBXCopyFilesBuildPhase section */ 15 | 58B511D91A9E6C8500147676 /* CopyFiles */ = { 16 | isa = PBXCopyFilesBuildPhase; 17 | buildActionMask = 2147483647; 18 | dstPath = "include/$(PRODUCT_NAME)"; 19 | dstSubfolderSpec = 16; 20 | files = ( 21 | ); 22 | runOnlyForDeploymentPostprocessing = 0; 23 | }; 24 | /* End PBXCopyFilesBuildPhase section */ 25 | 26 | /* Begin PBXFileReference section */ 27 | 134814201AA4EA6300B7C361 /* libIndySdk.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libIndySdk.a; sourceTree = BUILT_PRODUCTS_DIR; }; 28 | AD7073A123DF0AF000926D62 /* IndySdk-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "IndySdk-Bridging-Header.h"; sourceTree = ""; }; 29 | AD7073A223DF0AF000926D62 /* IndySdk.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IndySdk.swift; sourceTree = ""; }; 30 | B3E7B5891CC2AC0600A0062D /* IndySdk.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IndySdk.m; sourceTree = ""; }; 31 | /* End PBXFileReference section */ 32 | 33 | /* Begin PBXFrameworksBuildPhase section */ 34 | 58B511D81A9E6C8500147676 /* Frameworks */ = { 35 | isa = PBXFrameworksBuildPhase; 36 | buildActionMask = 2147483647; 37 | files = ( 38 | ); 39 | runOnlyForDeploymentPostprocessing = 0; 40 | }; 41 | /* End PBXFrameworksBuildPhase section */ 42 | 43 | /* Begin PBXGroup section */ 44 | 134814211AA4EA7D00B7C361 /* Products */ = { 45 | isa = PBXGroup; 46 | children = ( 47 | 134814201AA4EA6300B7C361 /* libIndySdk.a */, 48 | ); 49 | name = Products; 50 | sourceTree = ""; 51 | }; 52 | 58B511D21A9E6C8500147676 = { 53 | isa = PBXGroup; 54 | children = ( 55 | AD7073A223DF0AF000926D62 /* IndySdk.swift */, 56 | B3E7B5891CC2AC0600A0062D /* IndySdk.m */, 57 | AD7073A123DF0AF000926D62 /* IndySdk-Bridging-Header.h */, 58 | 134814211AA4EA7D00B7C361 /* Products */, 59 | ); 60 | sourceTree = ""; 61 | }; 62 | /* End PBXGroup section */ 63 | 64 | /* Begin PBXNativeTarget section */ 65 | 58B511DA1A9E6C8500147676 /* IndySdk */ = { 66 | isa = PBXNativeTarget; 67 | buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "IndySdk" */; 68 | buildPhases = ( 69 | 58B511D71A9E6C8500147676 /* Sources */, 70 | 58B511D81A9E6C8500147676 /* Frameworks */, 71 | 58B511D91A9E6C8500147676 /* CopyFiles */, 72 | ); 73 | buildRules = ( 74 | ); 75 | dependencies = ( 76 | ); 77 | name = IndySdk; 78 | productName = RCTDataManager; 79 | productReference = 134814201AA4EA6300B7C361 /* libIndySdk.a */; 80 | productType = "com.apple.product-type.library.static"; 81 | }; 82 | /* End PBXNativeTarget section */ 83 | 84 | /* Begin PBXProject section */ 85 | 58B511D31A9E6C8500147676 /* Project object */ = { 86 | isa = PBXProject; 87 | attributes = { 88 | LastUpgradeCheck = 0920; 89 | ORGANIZATIONNAME = Facebook; 90 | TargetAttributes = { 91 | 58B511DA1A9E6C8500147676 = { 92 | CreatedOnToolsVersion = 6.1.1; 93 | LastSwiftMigration = 1130; 94 | }; 95 | }; 96 | }; 97 | buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "IndySdk" */; 98 | compatibilityVersion = "Xcode 3.2"; 99 | developmentRegion = English; 100 | hasScannedForEncodings = 0; 101 | knownRegions = ( 102 | English, 103 | en, 104 | ); 105 | mainGroup = 58B511D21A9E6C8500147676; 106 | productRefGroup = 58B511D21A9E6C8500147676; 107 | projectDirPath = ""; 108 | projectRoot = ""; 109 | targets = ( 110 | 58B511DA1A9E6C8500147676 /* IndySdk */, 111 | ); 112 | }; 113 | /* End PBXProject section */ 114 | 115 | /* Begin PBXSourcesBuildPhase section */ 116 | 58B511D71A9E6C8500147676 /* Sources */ = { 117 | isa = PBXSourcesBuildPhase; 118 | buildActionMask = 2147483647; 119 | files = ( 120 | AD7073A323DF0AF000926D62 /* IndySdk.swift in Sources */, 121 | B3E7B58A1CC2AC0600A0062D /* IndySdk.m in Sources */, 122 | ); 123 | runOnlyForDeploymentPostprocessing = 0; 124 | }; 125 | /* End PBXSourcesBuildPhase section */ 126 | 127 | /* Begin XCBuildConfiguration section */ 128 | 58B511ED1A9E6C8500147676 /* Debug */ = { 129 | isa = XCBuildConfiguration; 130 | buildSettings = { 131 | ALWAYS_SEARCH_USER_PATHS = NO; 132 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 133 | CLANG_CXX_LIBRARY = "libc++"; 134 | CLANG_ENABLE_MODULES = YES; 135 | CLANG_ENABLE_OBJC_ARC = YES; 136 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 137 | CLANG_WARN_BOOL_CONVERSION = YES; 138 | CLANG_WARN_COMMA = YES; 139 | CLANG_WARN_CONSTANT_CONVERSION = YES; 140 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 141 | CLANG_WARN_EMPTY_BODY = YES; 142 | CLANG_WARN_ENUM_CONVERSION = YES; 143 | CLANG_WARN_INFINITE_RECURSION = YES; 144 | CLANG_WARN_INT_CONVERSION = YES; 145 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 146 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 147 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 148 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 149 | CLANG_WARN_STRICT_PROTOTYPES = YES; 150 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 151 | CLANG_WARN_UNREACHABLE_CODE = YES; 152 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 153 | COPY_PHASE_STRIP = NO; 154 | ENABLE_STRICT_OBJC_MSGSEND = YES; 155 | ENABLE_TESTABILITY = YES; 156 | GCC_C_LANGUAGE_STANDARD = gnu99; 157 | GCC_DYNAMIC_NO_PIC = NO; 158 | GCC_NO_COMMON_BLOCKS = YES; 159 | GCC_OPTIMIZATION_LEVEL = 0; 160 | GCC_PREPROCESSOR_DEFINITIONS = ( 161 | "DEBUG=1", 162 | "$(inherited)", 163 | ); 164 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 165 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 166 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 167 | GCC_WARN_UNDECLARED_SELECTOR = YES; 168 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 169 | GCC_WARN_UNUSED_FUNCTION = YES; 170 | GCC_WARN_UNUSED_VARIABLE = YES; 171 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 172 | MTL_ENABLE_DEBUG_INFO = YES; 173 | ONLY_ACTIVE_ARCH = YES; 174 | SDKROOT = iphoneos; 175 | }; 176 | name = Debug; 177 | }; 178 | 58B511EE1A9E6C8500147676 /* Release */ = { 179 | isa = XCBuildConfiguration; 180 | buildSettings = { 181 | ALWAYS_SEARCH_USER_PATHS = NO; 182 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 183 | CLANG_CXX_LIBRARY = "libc++"; 184 | CLANG_ENABLE_MODULES = YES; 185 | CLANG_ENABLE_OBJC_ARC = YES; 186 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 187 | CLANG_WARN_BOOL_CONVERSION = YES; 188 | CLANG_WARN_COMMA = YES; 189 | CLANG_WARN_CONSTANT_CONVERSION = YES; 190 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 191 | CLANG_WARN_EMPTY_BODY = YES; 192 | CLANG_WARN_ENUM_CONVERSION = YES; 193 | CLANG_WARN_INFINITE_RECURSION = YES; 194 | CLANG_WARN_INT_CONVERSION = YES; 195 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 196 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 197 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 198 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 199 | CLANG_WARN_STRICT_PROTOTYPES = YES; 200 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 201 | CLANG_WARN_UNREACHABLE_CODE = YES; 202 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 203 | COPY_PHASE_STRIP = YES; 204 | ENABLE_NS_ASSERTIONS = NO; 205 | ENABLE_STRICT_OBJC_MSGSEND = YES; 206 | GCC_C_LANGUAGE_STANDARD = gnu99; 207 | GCC_NO_COMMON_BLOCKS = YES; 208 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 209 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 210 | GCC_WARN_UNDECLARED_SELECTOR = YES; 211 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 212 | GCC_WARN_UNUSED_FUNCTION = YES; 213 | GCC_WARN_UNUSED_VARIABLE = YES; 214 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 215 | MTL_ENABLE_DEBUG_INFO = NO; 216 | SDKROOT = iphoneos; 217 | VALIDATE_PRODUCT = YES; 218 | }; 219 | name = Release; 220 | }; 221 | 58B511F01A9E6C8500147676 /* Debug */ = { 222 | isa = XCBuildConfiguration; 223 | buildSettings = { 224 | CLANG_ENABLE_MODULES = YES; 225 | FRAMEWORK_SEARCH_PATHS = ( 226 | "$(inherited)", 227 | "$(PROJECT_DIR)", 228 | ); 229 | HEADER_SEARCH_PATHS = ( 230 | "$(inherited)", 231 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 232 | "$(SRCROOT)/../../../React/**", 233 | "$(SRCROOT)/../../react-native/React/**", 234 | ); 235 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 236 | LIBRARY_SEARCH_PATHS = "$(inherited)"; 237 | OTHER_LDFLAGS = "-ObjC"; 238 | PRODUCT_NAME = IndySdk; 239 | SKIP_INSTALL = YES; 240 | SWIFT_OBJC_BRIDGING_HEADER = "IndySdk-Bridging-Header.h"; 241 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 242 | SWIFT_VERSION = 5.0; 243 | }; 244 | name = Debug; 245 | }; 246 | 58B511F11A9E6C8500147676 /* Release */ = { 247 | isa = XCBuildConfiguration; 248 | buildSettings = { 249 | CLANG_ENABLE_MODULES = YES; 250 | FRAMEWORK_SEARCH_PATHS = ( 251 | "$(inherited)", 252 | "$(PROJECT_DIR)", 253 | ); 254 | HEADER_SEARCH_PATHS = ( 255 | "$(inherited)", 256 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 257 | "$(SRCROOT)/../../../React/**", 258 | "$(SRCROOT)/../../react-native/React/**", 259 | ); 260 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 261 | LIBRARY_SEARCH_PATHS = "$(inherited)"; 262 | OTHER_LDFLAGS = "-ObjC"; 263 | PRODUCT_NAME = IndySdk; 264 | SKIP_INSTALL = YES; 265 | SWIFT_OBJC_BRIDGING_HEADER = "IndySdk-Bridging-Header.h"; 266 | SWIFT_VERSION = 5.0; 267 | }; 268 | name = Release; 269 | }; 270 | /* End XCBuildConfiguration section */ 271 | 272 | /* Begin XCConfigurationList section */ 273 | 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "IndySdk" */ = { 274 | isa = XCConfigurationList; 275 | buildConfigurations = ( 276 | 58B511ED1A9E6C8500147676 /* Debug */, 277 | 58B511EE1A9E6C8500147676 /* Release */, 278 | ); 279 | defaultConfigurationIsVisible = 0; 280 | defaultConfigurationName = Release; 281 | }; 282 | 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "IndySdk" */ = { 283 | isa = XCConfigurationList; 284 | buildConfigurations = ( 285 | 58B511F01A9E6C8500147676 /* Debug */, 286 | 58B511F11A9E6C8500147676 /* Release */, 287 | ); 288 | defaultConfigurationIsVisible = 0; 289 | defaultConfigurationName = Release; 290 | }; 291 | /* End XCConfigurationList section */ 292 | }; 293 | rootObject = 58B511D31A9E6C8500147676 /* Project object */; 294 | } 295 | -------------------------------------------------------------------------------- /ios/IndySdk.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/IndySdk.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /license-header: -------------------------------------------------------------------------------- 1 | Copyright 2019 ABSA Group Limited 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /license-header.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "ignore": [ 3 | ".git", 4 | "node_modules", 5 | "android/.gradle", 6 | "android/.idea", 7 | "android/build", 8 | "android/gradle", 9 | "android/gradlew*", 10 | "android/*.iml", 11 | "android/local.properties", 12 | "ios/IndySdk.xcodeproj", 13 | "ios/IndySdk.xcworkspace", 14 | ".gitattributes", 15 | ".gitignore", 16 | ".npmignore", 17 | ".prettierrc", 18 | "package.json", 19 | "yarn.lock", 20 | "**/*README.md", 21 | "LICENSE.md", 22 | "license-header*" 23 | ], 24 | "license": "license-header", 25 | "licenseFormats": { 26 | "java|js": { 27 | "prepend": "/**", 28 | "append": " */\n", 29 | "eachLine": { 30 | "prepend": " * " 31 | } 32 | }, 33 | "h|m|swift|gradle": { 34 | "prepend": "//", 35 | "append": "//\n", 36 | "eachLine": { 37 | "prepend": "// " 38 | } 39 | }, 40 | "podspec": { 41 | "append": "\n", 42 | "eachLine": { 43 | "prepend": "# " 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rn-indy-sdk", 3 | "title": "React Native Indy SDK Wrapper", 4 | "version": "0.1.11", 5 | "description": "React Native Indy SDK Wrapper", 6 | "main": "lib/index.js", 7 | "scripts": { 8 | "check-format": "prettier --check 'src/**/*.js'", 9 | "format": "prettier --write 'src/**/*.js'", 10 | "test": "echo \"Error: no test specified\" && exit 1", 11 | "build": "babel src/ -d lib/", 12 | "prepublish": "yarn run build" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/AbsaOSS/rn-indy-sdk.git", 17 | "baseUrl": "https://github.com/AbsaOSS/rn-indy-sdk" 18 | }, 19 | "keywords": [ 20 | "react-native", 21 | "Hyperledger Indy", 22 | "Hyperledger Aries", 23 | "Indy SDK" 24 | ], 25 | "author": { 26 | "name": "Jakub Koci", 27 | "email": "jakub.koci@absa.africa" 28 | }, 29 | "license": "Apache-2.0", 30 | "licenseFilename": "LICENSE.md", 31 | "readmeFilename": "README.md", 32 | "peerDependencies": { 33 | "react": ">= 16", 34 | "react-native": ">=0.59.0-rc.0 <1.0.x" 35 | }, 36 | "devDependencies": { 37 | "@babel/cli": "^7.8.4", 38 | "@babel/core": "^7.8.4", 39 | "@babel/preset-flow": "^7.8.3", 40 | "flow-bin": "^0.117.0", 41 | "husky": "^4.2.3", 42 | "prettier": "^2.0.3", 43 | "react": "^16.8.3", 44 | "react-native": "^0.59.10" 45 | }, 46 | "husky": { 47 | "hooks": { 48 | "pre-push": "npm run check-format" 49 | } 50 | }, 51 | "dependencies": { 52 | "buffer": "^6.0.2" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /rn-indy-sdk.podspec: -------------------------------------------------------------------------------- 1 | # Copyright 2019 ABSA Group Limited 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | 16 | require "json" 17 | 18 | package = JSON.parse(File.read(File.join(__dir__, "package.json"))) 19 | 20 | Pod::Spec.new do |s| 21 | s.name = "rn-indy-sdk" 22 | s.version = package["version"] 23 | s.summary = package["description"] 24 | s.description = <<-DESC 25 | rn-indy-sdk 26 | DESC 27 | s.homepage = "https://github.com/AbsaOSS/rn-indy-sdk" 28 | s.license = "Apache-2.0" 29 | # s.license = { :type => "Apache-2.0", :file => "LICENSE.md" } 30 | s.authors = { "Your Name" => "yourname@email.com" } 31 | s.platforms = { :ios => "10.0" } 32 | s.source = { :git => "https://github.com/AbsaOSS/rn-indy-sdk.git", :tag => "#{s.version}" } 33 | 34 | s.source_files = "ios/**/*.{h,m,swift}" 35 | s.requires_arc = true 36 | s.swift_version = '4.2' 37 | 38 | s.dependency "React" 39 | # ... 40 | # s.dependency "..." 41 | 42 | s.pod_target_xcconfig = { "FRAMEWORK_SEARCH_PATHS" => "${PODS_ROOT}/Frameworks" } 43 | end 44 | 45 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 ABSA Group Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | import { NativeModules } from 'react-native' 19 | import { Buffer } from 'buffer' 20 | 21 | export type CredOffer = { 22 | schema_id: string, 23 | cred_def_id: string, 24 | // Fields below can depend on Cred Def type 25 | nonce: string, 26 | key_correctness_proof: any, // 27 | } 28 | 29 | export type CredDefId = string 30 | export type CredDef = { 31 | id: string, // identifier of credential definition 32 | schemaId: string, // identifier of stored in ledger schema 33 | type: string, // type of the credential definition. CL is the only supported type now. 34 | tag: string, // allows to distinct between credential definitions for the same issuer and schema 35 | value: { 36 | // Dictionary with Credential Definition's data: 37 | primary: any, // primary credential public key, 38 | revocation: ?any, // revocation credential public key 39 | }, 40 | ver: string, // Version of the Credential Definition json 41 | } 42 | 43 | export type CredId = string 44 | 45 | // Credential json received from issuer 46 | export type Cred = { 47 | schema_id: string, 48 | cred_def_id: string, 49 | rev_reg_def_id: ?string, 50 | values: { 51 | // "attr1" : {"raw": "value1", "encoded": "value1_as_int" }, 52 | // "attr2" : {"raw": "value1", "encoded": "value1_as_int" } 53 | [string]: { raw: any, endcoded: any }, 54 | }, // , 55 | // Fields below can depend on Cred Def type 56 | signature: any, // 57 | signature_correctness_proof: any, // 58 | } 59 | 60 | export type Credential = { 61 | referent: CredId, // cred_id in the wallet 62 | attrs?: { 63 | // "key1":"raw_value1", 64 | // "key2":"raw_value2" 65 | [string]: any, 66 | }, 67 | schema_id: string, 68 | cred_def_id: string, 69 | rev_reg_id?: string, // Optional, 70 | cred_rev_id?: string, // Optional 71 | } 72 | 73 | export type MasterSecretId = string 74 | 75 | export type RequestedAttribute = string 76 | 77 | export type ProofRequest = { 78 | name: string, 79 | version: string, 80 | nonce: string, 81 | requested_attributes: { 82 | // set of requested attributes 83 | [attributeReferent: string]: { 84 | name: string, 85 | }, // : 86 | }, 87 | requested_predicates: { 88 | // set of requested predicates 89 | [attributePredicate: string]: {}, // : 90 | }, 91 | // Optional<> 92 | // If specified prover must proof non-revocation 93 | // for date in this interval for each attribute 94 | // (can be overridden on attribute level) 95 | non_revoked?: any, 96 | } 97 | 98 | export type Proof = { 99 | requested_proof: { 100 | revealed_attrs: { 101 | // requested_attr1_id: {sub_proof_index: number, raw: string, encoded: string}, 102 | // requested_attr4_id: {sub_proof_index: number: string, encoded: string}, 103 | [attributeReferent: string]: { 104 | raw: any, 105 | }, 106 | }, 107 | unrevealed_attrs: { 108 | // requested_attr3_id: {sub_proof_index: number} 109 | [attributeReferent: string]: {}, 110 | }, 111 | self_attested_attrs: { 112 | // requested_attr2_id: self_attested_value, 113 | [attributeReferent: string]: {}, 114 | }, 115 | requested_predicates: { 116 | // requested_predicate_1_referent: {sub_proof_index: int}, 117 | // requested_predicate_2_referent: {sub_proof_index: int}, 118 | [attributePredicate: string]: {}, 119 | }, 120 | }, 121 | proof: { 122 | proofs: [], // [ , , ], 123 | aggregated_proof: any, // 124 | }, 125 | identifiers: [], // [{schema_id, cred_def_id, Optional, Optional}] 126 | } 127 | 128 | export type RequestedCredentials = { 129 | self_attested_attributes: { 130 | // "self_attested_attribute_referent": string 131 | [attributeReferent: string]: string, 132 | }, 133 | requested_attributes: { 134 | // "requested_attribute_referent_1": {"cred_id": string, "timestamp": Optional, revealed: }}, 135 | // "requested_attribute_referent_2": {"cred_id": string, "timestamp": Optional, revealed: }} 136 | [attributeReferent: string]: {}, 137 | }, 138 | requested_predicates: { 139 | // "requested_predicates_referent_1": {"cred_id": string, "timestamp": Optional }}, 140 | [string]: {}, 141 | }, 142 | } 143 | 144 | export type SchemaId = string 145 | export type Schema = { 146 | id: SchemaId, 147 | name: string, 148 | // TODO It would be better to remove `status` attribute, because is part of our business domain and not Indy. 149 | // This custom attribute shows state of the credential request (when waiting for documents approval). 150 | status?: string, 151 | } 152 | 153 | /** 154 | * Json - all schemas json participating in the proof request 155 | * { 156 | * : , 157 | * : , 158 | * : , 159 | * } 160 | */ 161 | export type Schemas = { 162 | [SchemaId]: Schema, 163 | } 164 | 165 | /** 166 | * Json - all credential definitions json participating in the proof request 167 | * { 168 | * "cred_def1_id": , 169 | * "cred_def2_id": , 170 | * "cred_def3_id": , 171 | * } 172 | */ 173 | export type CredentialDefs = { 174 | [CredDefId]: CredDef, 175 | } 176 | 177 | /** 178 | * Json - all revocation states json participating in the proof request 179 | * { 180 | * "rev_reg_def1_id": { 181 | * "timestamp1": , 182 | * "timestamp2": , 183 | * }, 184 | * "rev_reg_def2_id": { 185 | * "timestamp3": 186 | * }, 187 | * "rev_reg_def3_id": { 188 | * "timestamp4": 189 | * }, 190 | * } 191 | */ 192 | export type RevStates = {} 193 | 194 | /** 195 | * Json - Request data json 196 | */ 197 | export type LedgerRequest = {} 198 | 199 | export type LedgerRequestResult = {} 200 | 201 | export type CredReq = { 202 | prover_did: string, 203 | cred_def_id: string, 204 | // Fields below can depend on Cred Def type 205 | blinded_ms?: any, // , 206 | blinded_ms_correctness_proof?: any, // , 207 | nonce?: string, 208 | } 209 | 210 | export type CredValues = Record 211 | 212 | interface CredValue { 213 | raw: string; 214 | encoded: string; // Raw value as number in string 215 | } 216 | 217 | /** 218 | * Credential request metadata json for further processing of received form Issuer credential. 219 | */ 220 | export type CredReqMetadata = {} 221 | 222 | /** 223 | * Json - revocation registry definition json related to in 224 | */ 225 | export type RevRegDef = {} 226 | 227 | export type RevRegId = string 228 | export type CredRevocId = string 229 | export type RevocRegDelta = Record 230 | export type TailsWriterConfig = { 231 | base_dir: string, 232 | uri_pattern: string, 233 | } 234 | 235 | export type Did = string 236 | 237 | export type Verkey = string 238 | 239 | export type WalletHandle = number 240 | export type PoolHandle = number 241 | export type BlobReaderHandle = number 242 | 243 | export type WalletRecord = { 244 | id: string, 245 | type: string, 246 | value: string, 247 | tags: {}, 248 | } 249 | 250 | export type WalletSearchHandle = number 251 | 252 | export type WalletRecrods = { 253 | totalCount?: string, 254 | records?: WalletRecord[], 255 | } 256 | 257 | const nymRoleValues = { 258 | TRUSTEE: 0, 259 | STEWARD: 2, 260 | TRUST_ANCHOR: 101, 261 | ENDORSER: 101, 262 | NETWORK_MONITOR: 201, 263 | } 264 | 265 | export type NymRole = $Keys 266 | 267 | export type GetNymResponse = { 268 | did: Did, 269 | verkey: Verkey, 270 | role: NymRole, 271 | } 272 | 273 | const { IndySdk } = NativeModules 274 | 275 | const indy = { 276 | // wallet 277 | 278 | createWallet(config: Object, credentials: Object): Promise { 279 | return IndySdk.createWallet(JSON.stringify(config), JSON.stringify(credentials)) 280 | }, 281 | 282 | openWallet(config: Object, credentials: Object): Promise { 283 | return IndySdk.openWallet(JSON.stringify(config), JSON.stringify(credentials)) 284 | }, 285 | 286 | closeWallet(wh: WalletHandle): Promise { 287 | return IndySdk.closeWallet(wh) 288 | }, 289 | 290 | deleteWallet(config: Object, credentials: Object): Promise { 291 | return IndySdk.deleteWallet(JSON.stringify(config), JSON.stringify(credentials)) 292 | }, 293 | 294 | // did 295 | 296 | /** 297 | * Value of passed `wh` parameter will be ignored in Android version of Indy native bridge, 298 | * because it keeps wallet as a private attribute. 299 | */ 300 | createAndStoreMyDid(wh: WalletHandle, did: Object): Promise<[Did, Verkey]> { 301 | if (Platform.OS === 'ios') { 302 | return IndySdk.createAndStoreMyDid(JSON.stringify(did), wh) 303 | } 304 | return IndySdk.createAndStoreMyDid(wh, JSON.stringify(did)) 305 | }, 306 | 307 | keyForDid(poolHandle: PoolHandle, wh: WalletHandle, did: Did): Promise { 308 | if (Platform.OS === 'ios') { 309 | return IndySdk.keyForDid(did, poolHandle, wh) 310 | } 311 | return IndySdk.keyForDid(poolHandle, wh, did) 312 | }, 313 | 314 | keyForLocalDid(wh: WalletHandle, did: Did): Promise { 315 | if (Platform.OS === 'ios') { 316 | return IndySdk.keyForLocalDid(did, wh) 317 | } 318 | return IndySdk.keyForLocalDid(wh, did) 319 | }, 320 | 321 | storeTheirDid(wh: WalletHandle, identity: {}) { 322 | if (Platform.OS === 'ios') { 323 | return IndySdk.storeTheirDid(JSON.stringify(identity), wh) 324 | } 325 | throw new Error(`Unsupported operation! Platform: ${Platform.OS}`) 326 | }, 327 | 328 | async listMyDidsWithMeta(wh) { 329 | if (Platform.OS === 'ios') { 330 | throw new Error(`Unsupported operation! Platform: ${Platform.OS}`) 331 | } 332 | return IndySdk.listMyDidsWithMeta(wh) 333 | }, 334 | 335 | async setDidMetadata(wh, did, metadata) { 336 | if (Platform.OS === 'ios') { 337 | throw new Error(`Unsupported operation! Platform: ${Platform.OS}`) 338 | } 339 | return IndySdk.setDidMetadata(wh, did, metadata) 340 | }, 341 | 342 | // pairwise 343 | 344 | createPairwise(wh: WalletHandle, theirDid: Did, myDid: Did, metadata: string = ''): Promise { 345 | if (Platform.OS === 'ios') { 346 | return IndySdk.createPairwise(theirDid, myDid, metadata, wh) 347 | } 348 | return IndySdk.createPairwise(wh, theirDid, myDid, metadata) 349 | }, 350 | 351 | async getPairwise(wh: WalletHandle, theirDid: Did): Promise { 352 | if (Platform.OS === 'ios') { 353 | return JSON.parse(await IndySdk.getPairwise(theirDid, wh)) 354 | } 355 | return JSON.parse(await IndySdk.getPairwise(wh, theirDid)) 356 | }, 357 | 358 | // crypto 359 | 360 | async cryptoAnonCrypt(recipientVk: Verkey, messageRaw: Buffer): Promise { 361 | if (Platform.OS === 'ios') { 362 | return IndySdk.cryptoAnonCrypt(messageRaw, recipientVk) 363 | } 364 | 365 | return Buffer.from(await IndySdk.cryptoAnonCrypt(recipientVk, Array.from(messageRaw))) 366 | }, 367 | 368 | async cryptoAnonDecrypt(wh: WalletHandle, recipientVk: Verkey, encryptedMsg: Buffer): Promise { 369 | if (Platform.OS === 'ios') { 370 | return IndySdk.cryptoAnonDecrypt(encryptedMsg, recipientVk, wh) 371 | } 372 | return Buffer.from(await IndySdk.cryptoAnonDecrypt(wh, recipientVk, Array.from(encryptedMsg))) 373 | }, 374 | 375 | async cryptoAuthCrypt(wh: WalletHandle, senderVk: Verkey, recipientVk: Verkey, messageRaw: Buffer): Promise { 376 | if (Platform.OS === 'ios') { 377 | return IndySdk.cryptoAuthCrypt(messageRaw, senderVk, recipientVk, wh) 378 | } 379 | return Buffer.from(await IndySdk.cryptoAuthCrypt(wh, senderVk, recipientVk, Array.from(messageRaw))) 380 | }, 381 | 382 | async cryptoAuthDecrypt(wh: WalletHandle, recipientVk: Verkey, encryptedMsgRaw: Buffer): Promise<[Verkey, Buffer]> { 383 | if (Platform.OS === 'ios') { 384 | return IndySdk.cryptoAuthDecrypt(encryptedMsgRaw, recipientVk, wh) 385 | } 386 | const [verkey, msg] = await IndySdk.cryptoAuthDecrypt(recipientVk, Array.from(encryptedMsgRaw)) 387 | return [verkey, Buffer.from(msg)] 388 | }, 389 | 390 | async cryptoSign(wh: WalletHandle, signerVk: string, message: Buffer): Promise { 391 | return Buffer.from(await IndySdk.cryptoSign(wh, signerVk, Array.from(message))) 392 | }, 393 | 394 | async cryptoVerify(signerVk: string, message: Buffer, signature: Buffer): Promise { 395 | return IndySdk.cryptoVerify(signerVk, Array.from(message), Array.from(signature)) 396 | }, 397 | 398 | async packMessage(wh: WalletHandle, message: Buffer, receiverKeys: Verkey[], senderVk: string): Promise { 399 | if (Platform.OS == 'ios') { 400 | return Buffer.from(await IndySdk.packMessage(wh, Array.from(message), JSON.stringify(receiverKeys), senderVk)) 401 | } 402 | return Buffer.from(await IndySdk.packMessage(wh, Array.from(message), receiverKeys, senderVk)) 403 | }, 404 | 405 | async unpackMessage(wh: WalletHandle, jwe: Buffer): Promise { 406 | return Buffer.from(await IndySdk.unpackMessage(wh, Array.from(jwe))) 407 | }, 408 | 409 | // pool 410 | 411 | createPoolLedgerConfig(poolName: string, poolConfig: {}): Promise { 412 | return IndySdk.createPoolLedgerConfig(poolName, JSON.stringify(poolConfig)) 413 | }, 414 | 415 | openPoolLedger(poolName: string, poolConfig: {} | undefined): Promise { 416 | if (Platform.OS === 'ios') { 417 | if (poolConfig === undefined) { 418 | return IndySdk.openLedger(poolName, null) 419 | } 420 | return IndySdk.openLedger(poolName, JSON.stringify(poolConfig)) 421 | } 422 | if (poolConfig === undefined) { 423 | return IndySdk.openPoolLedger(poolName, null) 424 | } 425 | return IndySdk.openPoolLedger(poolName, JSON.stringify(poolConfig)) 426 | }, 427 | 428 | setProtocolVersion(protocolVersion: number): Promise { 429 | return IndySdk.setProtocolVersion(protocolVersion) 430 | }, 431 | 432 | closePoolLedger(ph: PoolHandle): Promise { 433 | return IndySdk.closePoolLedger(ph) 434 | }, 435 | 436 | // ledger 437 | 438 | async submitRequest(poolHandle: PoolHandle, request: LedgerRequest): Promise { 439 | if (Platform.OS === 'ios') { 440 | return JSON.parse(await IndySdk.submitRequest(JSON.stringify(request), poolHandle)) 441 | } 442 | return JSON.parse(await IndySdk.submitRequest(poolHandle, JSON.stringify(request))) 443 | }, 444 | 445 | async signRequest(wh: WalletHandle, submitterDid: Did, request: LedgerRequest): Promise { 446 | if (Platform.OS === 'ios') { 447 | throw new Error(`Unsupported operation! Platform: ${Platform.OS}`) 448 | } 449 | return JSON.parse(await IndySdk.signRequest(wh, submitterDid, JSON.stringify(request))) 450 | }, 451 | 452 | async buildSchemaRequest(submitterDid: Did, data: string): Promise { 453 | if (Platform.OS === 'ios') { 454 | throw new Error(`Unsupported operation! Platform: ${Platform.OS}`) 455 | } 456 | 457 | return JSON.parse(await IndySdk.buildSchemaRequest(submitterDid, JSON.stringify(data))) 458 | }, 459 | 460 | async buildGetSchemaRequest(submitterDid: Did, id: string): Promise { 461 | return JSON.parse(await IndySdk.buildGetSchemaRequest(submitterDid, id)) 462 | }, 463 | 464 | async buildGetAttribRequest( 465 | submitterDid: Did | null, 466 | targetDid: Did, 467 | raw: string | null, 468 | hash: string | null, 469 | enc: string | null 470 | ): Promise { 471 | return JSON.parse(await IndySdk.buildGetAttribRequest(submitterDid, targetDid, raw, hash, enc)) 472 | }, 473 | 474 | async buildGetNymRequest(submitterDid: Did | null, targetDid: Did): Promise { 475 | return JSON.parse(await IndySdk.buildGetNymRequest(submitterDid, targetDid)) 476 | }, 477 | 478 | async parseGetNymResponse(response: LedgerRequestResult): Promise { 479 | return JSON.parse(await IndySdk.parseGetNymResponse(JSON.stringify(response))) 480 | }, 481 | 482 | async parseGetSchemaResponse(getSchemaResponse: LedgerRequestResult): Promise<[SchemaId, Schema]> { 483 | const [id, schema] = await IndySdk.parseGetSchemaResponse(JSON.stringify(getSchemaResponse)) 484 | return [id, JSON.parse(schema)] 485 | }, 486 | 487 | async buildCredDefRequest(submitterDid: Did, credDef: CredDef): Promise { 488 | if (Platform.OS === 'ios') { 489 | throw new Error(`Unsupported operation! Platform: ${Platform.OS}`) 490 | } 491 | return JSON.parse(await IndySdk.buildCredDefRequest(submitterDid, JSON.stringify(credDef))) 492 | }, 493 | 494 | async buildGetCredDefRequest(submitterDid: Did, id: string): Promise { 495 | return JSON.parse(await IndySdk.buildGetCredDefRequest(submitterDid, id)) 496 | }, 497 | 498 | async parseGetCredDefResponse(getCredDefResponse: LedgerRequestResult): Promise<[CredDefId, CredDef]> { 499 | const [credDefId, credDef] = await IndySdk.parseGetCredDefResponse(JSON.stringify(getCredDefResponse)) 500 | return [credDefId, JSON.parse(credDef)] 501 | }, 502 | 503 | async proverCreateMasterSecret(wh: WalletHandle, masterSecretId: ?MasterSecretId): Promise { 504 | if (Platform.OS === 'ios') { 505 | return IndySdk.proverCreateMasterSecret(masterSecretId, wh) 506 | } 507 | return IndySdk.proverCreateMasterSecret(wh, masterSecretId) 508 | }, 509 | 510 | async proverCreateCredentialReq( 511 | wh: WalletHandle, 512 | proverDid: Did, 513 | credOffer: CredOffer, 514 | credDef: CredDef, 515 | masterSecretId: MasterSecretId 516 | ): Promise<[CredReq, CredReqMetadata]> { 517 | if (Platform.OS === 'ios') { 518 | const [credReq, credReqMetadata] = await IndySdk.proverCreateCredentialReq( 519 | JSON.stringify(credOffer), 520 | JSON.stringify(credDef), 521 | proverDid, 522 | masterSecretId, 523 | wh 524 | ) 525 | return [JSON.parse(credReq), JSON.parse(credReqMetadata)] 526 | } 527 | const [credReq, credReqMetadata] = await IndySdk.proverCreateCredentialReq( 528 | wh, 529 | proverDid, 530 | JSON.stringify(credOffer), 531 | JSON.stringify(credDef), 532 | masterSecretId 533 | ) 534 | return [JSON.parse(credReq), JSON.parse(credReqMetadata)] 535 | }, 536 | 537 | proverStoreCredential( 538 | wh: WalletHandle, 539 | credId: CredId, 540 | credReqMetadata: CredReqMetadata, 541 | cred: Cred, 542 | credDef: CredDef, 543 | revRegDef: ?RevRegDef 544 | ): Promise { 545 | if (Platform.OS === 'ios') { 546 | return IndySdk.proverStoreCredential( 547 | JSON.stringify(cred), 548 | credId, 549 | JSON.stringify(credReqMetadata), 550 | JSON.stringify(credDef), 551 | revRegDef && JSON.stringify(revRegDef), 552 | wh 553 | ) 554 | } 555 | return IndySdk.proverStoreCredential( 556 | wh, 557 | credId, 558 | JSON.stringify(credReqMetadata), 559 | JSON.stringify(cred), 560 | JSON.stringify(credDef), 561 | revRegDef && JSON.stringify(revRegDef) 562 | ) 563 | }, 564 | 565 | async proverGetCredential(wh: WalletHandle, credId: CredId): Promise { 566 | if (Platform.OS === 'ios') { 567 | return JSON.parse(await IndySdk.proverGetCredential(credId, wh)) 568 | } 569 | return JSON.parse(await IndySdk.proverGetCredential(wh, credId)) 570 | }, 571 | 572 | // TODO: add proverDeleteCredential() method 573 | 574 | // NOTE: This method is deprecated because immediately returns all fetched credentials. Use proverSearchCredentials() to fetch records by small batches. 575 | async proverGetCredentials(wh: WalletHandle, filter: {} = {}): Promise { 576 | if (Platform.OS === 'ios') { 577 | return JSON.parse(await IndySdk.proverGetCredentials(JSON.stringify(filter), wh)) 578 | } 579 | return JSON.parse(await IndySdk.proverGetCredentials(wh, JSON.stringify(filter))) 580 | }, 581 | 582 | // TODO: add proverSearchCredentials() method 583 | // TODO: add proverFetchCredentials() method 584 | // TODO: add proverCloseCredentialsSearch() method 585 | 586 | // TODO Add return flow type. 587 | // It needs little investigation, because is doesn't seem to be same format as Credential stored in wallet. 588 | // NOTE: This method is deprecated because immediately returns all fetched credentials. proverSearchCredentialsForProofReq to fetch records by small batches. 589 | async proverGetCredentialsForProofReq(wh: WalletHandle, proofRequest: ProofRequest) { 590 | if (Platform.OS == 'ios') { 591 | return JSON.parse(await IndySdk.proverGetCredentialsForProofReq(JSON.stringify(proofRequest), wh)) 592 | } 593 | return JSON.parse(await IndySdk.proverGetCredentialsForProofReq(wh, JSON.stringify(proofRequest))) 594 | }, 595 | 596 | async proverSearchCredentialsForProofReq(wh: WalletHandle, proofRequest: ProofRequest, extraQuery: {} | null) { 597 | //The NodeJS IndySDK wrapper differs from the Java and iOS wrappers in this call--it allows extraQuery to be a wql query object or null. 598 | return await IndySdk.proverSearchCredentialsForProofReq( 599 | wh, 600 | JSON.stringify(proofRequest), 601 | JSON.stringify(extraQuery ?? {}) 602 | ) 603 | }, 604 | 605 | async proverFetchCredentialsForProofReq(sh: number, itemReferent: string, count: number) { 606 | return JSON.parse(await IndySdk.proverFetchCredentialsForProofReq(sh, itemReferent, count)) 607 | }, 608 | 609 | async proverCloseCredentialsSearchForProofReq(sh: number) { 610 | return await IndySdk.proverCloseCredentialsSearchForProofReq(sh) 611 | }, 612 | 613 | async proverCreateProof( 614 | wh: WalletHandle, 615 | proofReq: ProofRequest, 616 | requestedCredentials: RequestedCredentials, 617 | masterSecretName: MasterSecretId, 618 | schemas: Schemas, 619 | credentialDefs: CredentialDefs, 620 | revStates: RevStates = {} 621 | ): Promise { 622 | if (Platform.OS == 'ios') { 623 | return JSON.parse( 624 | await IndySdk.proverCreateProofForRequest( 625 | JSON.stringify(proofReq), 626 | JSON.stringify(requestedCredentials), 627 | masterSecretName, 628 | JSON.stringify(schemas), 629 | JSON.stringify(credentialDefs), 630 | JSON.stringify(revStates), 631 | wh 632 | ) 633 | ) 634 | } 635 | return JSON.parse( 636 | await IndySdk.proverCreateProof( 637 | wh, 638 | JSON.stringify(proofReq), 639 | JSON.stringify(requestedCredentials), 640 | masterSecretName, 641 | JSON.stringify(schemas), 642 | JSON.stringify(credentialDefs), 643 | JSON.stringify(revStates) 644 | ) 645 | ) 646 | }, 647 | 648 | async verifierVerifyProof( 649 | proofRequest: IndyProofRequest, 650 | proof: Proof, 651 | schemas: Schemas, 652 | credentialDefs: CredentialDefs, 653 | revRegDef: ?RevRegDef, 654 | revStates: RevStates 655 | ): Promise { 656 | return IndySdk.verifierVerifyProof( 657 | JSON.stringify(proofRequest), 658 | JSON.stringify(proof), 659 | JSON.stringify(schemas), 660 | JSON.stringify(credentialDefs), 661 | revRegDef && JSON.stringify(revRegDef), 662 | JSON.stringify(revStates) 663 | ) 664 | }, 665 | 666 | async appendTxnAuthorAgreementAcceptanceToRequest( 667 | request: LedgerRequest, 668 | text: string, 669 | version: string, 670 | taaDigest: string, 671 | mechanism: string, 672 | time: number 673 | ): Promise { 674 | if (Platform.OS === 'ios') { 675 | throw new Error(`Unsupported operation! Platform: ${Platform.OS}`) 676 | } 677 | return JSON.parse( 678 | await IndySdk.appendTxnAuthorAgreementAcceptanceToRequest( 679 | JSON.stringify(request), 680 | text, 681 | version, 682 | taaDigest, 683 | mechanism, 684 | time 685 | ) 686 | ) 687 | }, 688 | 689 | async buildGetTxnAuthorAgreementRequest(submitterDid: Did, data: string): Promise { 690 | if (Platform.OS === 'ios') { 691 | throw new Error(`Unsupported operation! Platform: ${Platform.OS}`) 692 | } 693 | return JSON.parse(await IndySdk.buildGetTxnAuthorAgreementRequest(submitterDid, data)) 694 | }, 695 | 696 | // non_secrets 697 | 698 | async addWalletRecord(wh: WalletHandle, type: string, id: string, value: string, tags: {}): Promise { 699 | return IndySdk.addWalletRecord(wh, type, id, value, JSON.stringify(tags)) 700 | }, 701 | 702 | async updateWalletRecordValue(wh: WalletHandle, type: string, id: string, value: string): Promise { 703 | return IndySdk.updateWalletRecordValue(wh, type, id, value) 704 | }, 705 | 706 | async updateWalletRecordTags(wh: WalletHandle, type: string, id: string, tags: {}): Promise { 707 | return IndySdk.updateWalletRecordTags(wh, type, id, JSON.stringify(tags)) 708 | }, 709 | 710 | async addWalletRecordTags(wh: WalletHandle, type: string, id: string, tags: {}): Promise { 711 | return IndySdk.addWalletRecordTags(wh, type, id, JSON.stringify(tags)) 712 | }, 713 | 714 | async deleteWalletRecordTags(wh: WalletHandle, type: string, id: string, tagNames: []): Promise { 715 | return IndySdk.deleteWalletRecordTags(wh, type, id, JSON.stringify(tagNames)) 716 | }, 717 | 718 | async deleteWalletRecord(wh: WalletHandle, type: string, id: string): Promise { 719 | return IndySdk.deleteWalletRecord(wh, type, id) 720 | }, 721 | 722 | async getWalletRecord(wh: WalletHandle, type: string, id: string, options: {}): Promise { 723 | return JSON.parse(await IndySdk.getWalletRecord(wh, type, id, JSON.stringify(options))) 724 | }, 725 | 726 | async openWalletSearch(wh: WalletHandle, type: string, query: {}, options: {}): Promise { 727 | return IndySdk.openWalletSearch(wh, type, JSON.stringify(query), JSON.stringify(options)) 728 | }, 729 | 730 | async fetchWalletSearchNextRecords(wh: WalletHandle, sh: WalletSearchHandle, count: number): Promise { 731 | return JSON.parse(await IndySdk.fetchWalletSearchNextRecords(wh, sh, count)) 732 | }, 733 | 734 | async closeWalletSearch(sh: WalletSearchHandle): Promise { 735 | return IndySdk.closeWalletSearch(sh) 736 | }, 737 | 738 | // Anoncreds 739 | 740 | async issuerCreateSchema(did: Did, name: string, version: string, attributes: string[]): Promise<[SchemaId, Schema]> { 741 | if (Platform.OS === 'ios') { 742 | throw new Error(`Unsupported operation! Platform: ${Platform.OS}`) 743 | } 744 | 745 | const [schemaId, schema] = await IndySdk.issuerCreateSchema(did, name, version, JSON.stringify(attributes)) 746 | return [schemaId, JSON.parse(schema)] 747 | }, 748 | 749 | async issuerCreateAndStoreCredentialDef( 750 | wh: WalletHandle, 751 | issuerDid: Did, 752 | schema: Schema, 753 | tag: string, 754 | signatureType: string, 755 | config: {} 756 | ): Promise<[CredDefId, CredDef]> { 757 | if (Platform.OS === 'ios') { 758 | throw new Error(`Unsupported operation! Platform: ${Platform.OS}`) 759 | } 760 | 761 | const [credDefId, credDef] = await IndySdk.issuerCreateAndStoreCredentialDef( 762 | wh, 763 | issuerDid, 764 | JSON.stringify(schema), 765 | tag, 766 | signatureType, 767 | JSON.stringify(config) 768 | ) 769 | return [credDefId, JSON.parse(credDef)] 770 | }, 771 | 772 | async issuerCreateCredentialOffer(wh: WalletHandle, credDefId: CredDefId): Promise { 773 | if (Platform.OS === 'ios') { 774 | throw new Error(`Unsupported operation! Platform: ${Platform.OS}`) 775 | } 776 | 777 | return JSON.parse(await IndySdk.issuerCreateCredentialOffer(wh, credDefId)) 778 | }, 779 | 780 | async issuerCreateCredential( 781 | wh: WalletHandle, 782 | credOffer: CredOffer, 783 | credReq: CredReq, 784 | credvalues: CredValues, 785 | revRegId: RevRegId, 786 | blobStorageReaderHandle: BlobReaderHandle 787 | ): Promise<[Credential, CredRevocId, RevocRegDelta]> { 788 | if (Platform.OS === 'ios') { 789 | throw new Error(`Unsupported operation! Platform: ${Platform.OS}`) 790 | } 791 | const [credJson, revocId, revocRegDelta] = await IndySdk.issuerCreateCredential( 792 | wh, 793 | JSON.stringify(credOffer), 794 | JSON.stringify(credReq), 795 | JSON.stringify(credvalues), 796 | revRegId, 797 | blobStorageReaderHandle 798 | ) 799 | return [JSON.parse(credJson), revocId, JSON.parse(revocRegDelta)] 800 | }, 801 | 802 | // blob_storage 803 | 804 | async openBlobStorageReader(type: string, tailsWriterConfig: TailsWriterConfig): Promise { 805 | if (Platform.OS === 'ios') { 806 | throw new Error(`Unsupported operation! Platform: ${Platform.OS}`) 807 | } 808 | 809 | return JSON.parse(await IndySdk.openBlobStorageReader(type, JSON.stringify(tailsWriterConfig))) 810 | }, 811 | } 812 | 813 | const indyErrors = { 814 | 100: 'CommonInvalidParam1', 815 | 101: 'CommonInvalidParam2', 816 | 102: 'CommonInvalidParam3', 817 | 103: 'CommonInvalidParam4', 818 | 104: 'CommonInvalidParam5', 819 | 105: 'CommonInvalidParam6', 820 | 106: 'CommonInvalidParam7', 821 | 107: 'CommonInvalidParam8', 822 | 108: 'CommonInvalidParam9', 823 | 109: 'CommonInvalidParam10', 824 | 110: 'CommonInvalidParam11', 825 | 111: 'CommonInvalidParam12', 826 | 112: 'CommonInvalidState', 827 | 113: 'CommonInvalidStructure', 828 | 114: 'CommonIOError', 829 | 115: 'CommonInvalidParam13', 830 | 116: 'CommonInvalidParam14', 831 | 200: 'WalletInvalidHandle', 832 | 201: 'WalletUnknownTypeError', 833 | 202: 'WalletTypeAlreadyRegisteredError', 834 | 203: 'WalletAlreadyExistsError', 835 | 204: 'WalletNotFoundError', 836 | 205: 'WalletIncompatiblePoolError', 837 | 206: 'WalletAlreadyOpenedError', 838 | 207: 'WalletAccessFailed', 839 | 208: 'WalletInputError', 840 | 209: 'WalletDecodingError', 841 | 210: 'WalletStorageError', 842 | 211: 'WalletEncryptionError', 843 | 212: 'WalletItemNotFound', 844 | 213: 'WalletItemAlreadyExists', 845 | 214: 'WalletQueryError', 846 | 300: 'PoolLedgerNotCreatedError', 847 | 301: 'PoolLedgerInvalidPoolHandle', 848 | 302: 'PoolLedgerTerminated', 849 | 303: 'LedgerNoConsensusError', 850 | 304: 'LedgerInvalidTransaction', 851 | 305: 'LedgerSecurityError', 852 | 306: 'PoolLedgerConfigAlreadyExistsError', 853 | 307: 'PoolLedgerTimeout', 854 | 308: 'PoolIncompatibleProtocolVersion', 855 | 309: 'LedgerNotFound', 856 | 400: 'AnoncredsRevocationRegistryFullError', 857 | 401: 'AnoncredsInvalidUserRevocId', 858 | 404: 'AnoncredsMasterSecretDuplicateNameError', 859 | 405: 'AnoncredsProofRejected', 860 | 406: 'AnoncredsCredentialRevoked', 861 | 407: 'AnoncredsCredDefAlreadyExistsError', 862 | 500: 'UnknownCryptoTypeError', 863 | 600: 'DidAlreadyExistsError', 864 | 700: 'PaymentUnknownMethodError', 865 | 701: 'PaymentIncompatibleMethodsError', 866 | 702: 'PaymentInsufficientFundsError', 867 | 703: 'PaymentSourceDoesNotExistError', 868 | 704: 'PaymentOperationNotSupportedError', 869 | 705: 'PaymentExtraFundsError', 870 | 706: 'TransactionNotAllowedError', 871 | } 872 | 873 | function wrapIndyCallWithErrorHandling(func) { 874 | return async (...args) => { 875 | // Wrap try/catch around indy func 876 | try { 877 | return await func(...args) 878 | } catch (e) { 879 | // Try to parse e.message as it should be a 880 | // JSON string for Indy errors (at least on Android) 881 | // Parsing could also go wrong. In this case we just 882 | // want to throw the native side error 883 | let parse 884 | try { 885 | parse = JSON.parse(e.message) 886 | } catch { 887 | throw e 888 | } 889 | 890 | if (Platform.OS === 'ios') { 891 | const { indyCode, message } = parse 892 | if (!isNaN(indyCode) && indyErrors.hasOwnProperty(indyCode)) { 893 | const indyName = indyErrors[indyCode] 894 | const indyErrorFromIOS = { 895 | name: 'IndyError', 896 | message, 897 | indyCode: indyCode, 898 | indyName: indyName, 899 | indyCurrentErrorJson: null, 900 | } 901 | throw indyErrorFromIOS 902 | } 903 | } 904 | 905 | throw parse 906 | } 907 | } 908 | } 909 | 910 | // This adds indy error handling to all methods to 911 | // transform the string messages into JSON error objects 912 | const indyWithErrorHandling = Object.fromEntries( 913 | Object.entries(indy).map(([funcName, funcImpl]) => [funcName, wrapIndyCallWithErrorHandling(funcImpl)]) 914 | ) 915 | 916 | export default indyWithErrorHandling 917 | --------------------------------------------------------------------------------