├── .gitattributes ├── .github └── workflows │ └── actions.yml ├── .gitignore ├── LICENSE ├── README.md ├── android ├── README.md ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── io │ │ └── parity │ │ └── substrateSign │ │ ├── SubstrateSignModule.java │ │ └── SubstrateSignPackage.java │ └── jniLibs │ ├── arm64-v8a │ └── libsigner.so │ ├── armeabi-v7a │ └── libsigner.so │ ├── x86 │ └── libsigner.so │ └── x86_64 │ └── libsigner.so ├── index.d.ts ├── index.js ├── ios ├── SubstrateSign-Bridging-Header.h ├── SubstrateSign.h ├── SubstrateSign.m ├── SubstrateSign.swift ├── SubstrateSign.xcodeproj │ └── project.pbxproj ├── SubstrateSign.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── libsigner.a └── signer.h ├── package.json ├── react-native-substrate-sign.podspec ├── rust └── signer │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ ├── eth.rs │ ├── export │ ├── android │ │ ├── arg.rs │ │ ├── mod.rs │ │ ├── ret.rs │ │ └── util.rs │ ├── ios │ │ ├── arg.rs │ │ ├── mod.rs │ │ └── ret.rs │ └── mod.rs │ ├── lib.rs │ ├── result.rs │ └── sr25519.rs └── scripts ├── build.sh ├── init.sh └── variables.sh /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | *.so binary 5 | yarn.lock -diff 6 | -------------------------------------------------------------------------------- /.github/workflows/actions.yml: -------------------------------------------------------------------------------- 1 | name: iOS Rust Build & Unit Test 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - master 8 | - stable 9 | jobs: 10 | check: 11 | name: Check 12 | runs-on: macos-latest 13 | steps: 14 | - name: Checkout sources 15 | uses: actions/checkout@v2 16 | with: 17 | fetch-depth: 50 18 | 19 | - name: Checkout submodules 20 | shell: bash 21 | run: git submodule update --init --recursive 22 | 23 | - name: Install 1.41.1 toolchain 24 | uses: actions-rs/toolchain@v1.0.5 25 | with: 26 | toolchain: stable 27 | profile: minimal 28 | override: true 29 | 30 | - name: Cache cargo index 31 | uses: actions/cache@v1.1.2 32 | with: 33 | path: ~/.cargo/git 34 | key: ${{ runner.os }}-cargo-git-${{ hashFiles('**/Cargo.lock') }} 35 | 36 | - name: Cache sccache MacOS 37 | uses: actions/cache@v1.1.2 38 | with: 39 | path: "/Users/runner/Library/Caches/Mozilla.sccache" 40 | key: ${{ runner.os }}-sccache-build-tests-${{ hashFiles('**/Cargo.lock') }} 41 | 42 | - name: Install & start sccache 43 | shell: bash 44 | run: | 45 | VERSION="0.2.13" 46 | PLATFORM="x86_64-apple-darwin" 47 | BASENAME="sccache-$VERSION-$PLATFORM" 48 | URL="https://github.com/mozilla/sccache/releases/download/$VERSION/$BASENAME.tar.gz" 49 | echo "Download sccache from " "$URL" 50 | curl -LO "$URL" 51 | tar -xzvf "$BASENAME.tar.gz" 52 | ls $BASENAME/ 53 | ./$BASENAME/sccache --start-server 54 | echo "$(pwd)/$BASENAME" >> "$GITHUB_PATH" 55 | echo "RUSTC_WRAPPER=sccache" >> "$GITHUB_ENV" 56 | 57 | - name: Rust Unit Test 58 | run: | 59 | cd ./rust/signer 60 | cargo test 61 | 62 | - name: Stop sccache 63 | if: always() 64 | run: sccache --stop-server 65 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | NDK/ 5 | 6 | # node.js 7 | # 8 | node_modules/ 9 | npm-debug.log 10 | yarn-error.log 11 | 12 | # Xcode 13 | # 14 | build/ 15 | *.pbxuser 16 | !default.pbxuser 17 | *.mode1v3 18 | !default.mode1v3 19 | *.mode2v3 20 | !default.mode2v3 21 | *.perspectivev3 22 | !default.perspectivev3 23 | xcuserdata 24 | *.xccheckout 25 | *.moved-aside 26 | DerivedData 27 | *.hmap 28 | *.ipa 29 | *.xcuserstate 30 | project.xcworkspace 31 | 32 | # Android/IntelliJ 33 | # 34 | build/ 35 | .idea 36 | .gradle 37 | local.properties 38 | *.iml 39 | 40 | ios/.DS_Store 41 | android.iml 42 | android/.gradle 43 | # BUCK 44 | buck-out/ 45 | \.buckd/ 46 | *.keystore 47 | 48 | #rust 49 | rust/signer/target 50 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-native-substrate-sign 2 | 3 | [![npm version](https://badge.fury.io/js/react-native-substrate-sign.svg)](https://badge.fury.io/js/react-native-substrate-sign) 4 | 5 | This React Native library packages practical crypto functions written in Rust for Substrate, Polkadot and Ethereum. Originally used for [Parity Signer](https://github.com/paritytech/parity-signer/). 6 | 7 | ## Getting started 8 | 9 | ```shell script 10 | yarn add react-native-substrate-sign 11 | cd ios && pod install && cd .. 12 | ``` 13 | 14 | ## Usage 15 | 16 | All the functions could be find in the `index.d.ts` file. They are wrapped with async behaviors, since we need access to Rust runtime, be sure to use `await` or `then` to access the result. 17 | 18 | ```javascript 19 | import SubstrateSign from 'react-native-substrate-sign'; 20 | 21 | async function getRandomPhrase(){ 22 | const newRandomPhrase = SubstrateSign.randomPhrase(12); 23 | } 24 | ``` 25 | 26 | ## Build and Develop 27 | 28 | ### Requirements 29 | 30 | - `node.js` ( `>=10`) 31 | - `yarn` (tested on `1.6.0`) 32 | - `rustup` (tested on `rustup 1.21.0`) 33 | - `rustc` (tested on `rustc 1.41.1`, from 1.42.0 rust [dropped 32-bit apple target support](https://blog.rust-lang.org/2020/01/03/reducing-support-for-32-bit-apple-targets.html)) 34 | - `cargo` (tested on `cargo 1.41.0`) 35 | - `android_ndk` (tested on `r21`, can be downloaded [here](https://developer.android.com/ndk/downloads)) 36 | - `$NDK_HOME` envarionment variable set to ndk home directory (eg. `/usr/local/opt/android-ndk`) 37 | 38 | \* It's recommended to install **Android Studio** and use that to install the necessary build tools and SDKs for the Android version you want to test on. It's also the best way to test in the emulator. 39 | 40 | ### Setup 41 | 42 | - Use the following script to install the required rust toolchains. 43 | 44 | ```shell script 45 | ./scripts/init.sh 46 | ``` 47 | 48 | 49 | ### Develop 50 | After update the rust code, you need to change the following files for updating the interface to native android and ios code. 51 | 52 | - ios/signer.h 53 | - ios/SubstrateSign.m 54 | - ios/SubstrateSign.swift 55 | - android/src/main/java/com/reactlibrary/SubstrateSignModule.java 56 | - index.js 57 | - index.d.ts 58 | 59 | ### Test 60 | 61 | - To run the rust test 62 | 63 | ```shell script 64 | yarn test 65 | ``` 66 | 67 | ### Build 68 | 69 | - Use the following script to build the dynamic library for Android and static library for iOS. 70 | 71 | ```shell script 72 | ./scripts/build.sh 73 | ``` 74 | -------------------------------------------------------------------------------- /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 | // android/build.gradle 2 | 3 | // based on: 4 | // 5 | // * https://github.com/facebook/react-native/blob/0.60-stable/template/android/build.gradle 6 | // original location: 7 | // - https://github.com/facebook/react-native/blob/0.58-stable/local-cli/templates/HelloWorld/android/build.gradle 8 | // 9 | // * https://github.com/facebook/react-native/blob/0.60-stable/template/android/app/build.gradle 10 | // original location: 11 | // - https://github.com/facebook/react-native/blob/0.58-stable/local-cli/templates/HelloWorld/android/app/build.gradle 12 | 13 | def DEFAULT_COMPILE_SDK_VERSION = 28 14 | def DEFAULT_BUILD_TOOLS_VERSION = '28.0.3' 15 | def DEFAULT_MIN_SDK_VERSION = 16 16 | def DEFAULT_TARGET_SDK_VERSION = 28 17 | 18 | def safeExtGet(prop, fallback) { 19 | rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback 20 | } 21 | 22 | apply plugin: 'com.android.library' 23 | apply plugin: 'maven' 24 | 25 | buildscript { 26 | // The Android Gradle plugin is only required when opening the android folder stand-alone. 27 | // This avoids unnecessary downloads and potential conflicts when the library is included as a 28 | // module dependency in an application project. 29 | // ref: https://docs.gradle.org/current/userguide/tutorial_using_tasks.html#sec:build_script_external_dependencies 30 | if (project == rootProject) { 31 | repositories { 32 | google() 33 | jcenter() 34 | } 35 | dependencies { 36 | classpath 'com.android.tools.build:gradle:3.4.1' 37 | } 38 | } 39 | } 40 | 41 | apply plugin: 'com.android.library' 42 | apply plugin: 'maven' 43 | 44 | android { 45 | compileSdkVersion safeExtGet('compileSdkVersion', DEFAULT_COMPILE_SDK_VERSION) 46 | buildToolsVersion safeExtGet('buildToolsVersion', DEFAULT_BUILD_TOOLS_VERSION) 47 | defaultConfig { 48 | minSdkVersion safeExtGet('minSdkVersion', DEFAULT_MIN_SDK_VERSION) 49 | targetSdkVersion safeExtGet('targetSdkVersion', DEFAULT_TARGET_SDK_VERSION) 50 | versionCode 1 51 | versionName "1.0" 52 | } 53 | lintOptions { 54 | abortOnError false 55 | } 56 | } 57 | 58 | repositories { 59 | // ref: https://www.baeldung.com/maven-local-repository 60 | mavenLocal() 61 | maven { 62 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 63 | url "$rootDir/../node_modules/react-native/android" 64 | } 65 | maven { 66 | // Android JSC is installed from npm 67 | url "$rootDir/../node_modules/jsc-android/dist" 68 | } 69 | google() 70 | jcenter() 71 | } 72 | 73 | dependencies { 74 | //noinspection GradleDynamicVersion 75 | implementation 'com.facebook.react:react-native:+' // From node_modules 76 | } 77 | 78 | def configureReactNativePom(def pom) { 79 | def packageJson = new groovy.json.JsonSlurper().parseText(file('../package.json').text) 80 | 81 | pom.project { 82 | name packageJson.title 83 | artifactId packageJson.name 84 | version = packageJson.version 85 | group = "io.parity.substrateSign" 86 | description packageJson.description 87 | url packageJson.repository.baseUrl 88 | 89 | licenses { 90 | license { 91 | name packageJson.license 92 | url packageJson.repository.baseUrl + '/blob/master/' + packageJson.licenseFilename 93 | distribution 'repo' 94 | } 95 | } 96 | 97 | developers { 98 | developer { 99 | id packageJson.author.username 100 | name packageJson.author.name 101 | } 102 | } 103 | } 104 | } 105 | 106 | afterEvaluate { project -> 107 | // some Gradle build hooks ref: 108 | // https://www.oreilly.com/library/view/gradle-beyond-the/9781449373801/ch03.html 109 | task androidJavadoc(type: Javadoc) { 110 | source = android.sourceSets.main.java.srcDirs 111 | classpath += files(android.bootClasspath) 112 | classpath += files(project.getConfigurations().getByName('compile').asList()) 113 | include '**/*.java' 114 | } 115 | 116 | task androidJavadocJar(type: Jar, dependsOn: androidJavadoc) { 117 | classifier = 'javadoc' 118 | from androidJavadoc.destinationDir 119 | } 120 | 121 | task androidSourcesJar(type: Jar) { 122 | classifier = 'sources' 123 | from android.sourceSets.main.java.srcDirs 124 | include '**/*.java' 125 | } 126 | 127 | android.libraryVariants.all { variant -> 128 | def name = variant.name.capitalize() 129 | def javaCompileTask = variant.javaCompileProvider.get() 130 | 131 | task "jar${name}"(type: Jar, dependsOn: javaCompileTask) { 132 | from javaCompileTask.destinationDir 133 | } 134 | } 135 | 136 | artifacts { 137 | archives androidSourcesJar 138 | archives androidJavadocJar 139 | } 140 | 141 | task installArchives(type: Upload) { 142 | configuration = configurations.archives 143 | repositories.mavenDeployer { 144 | // Deploy to react-native-event-bridge/maven, ready to publish to npm 145 | repository url: "file://${projectDir}/../android/maven" 146 | configureReactNativePom pom 147 | } 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /android/src/main/java/io/parity/substrateSign/SubstrateSignModule.java: -------------------------------------------------------------------------------- 1 | package io.parity.substrateSign; 2 | 3 | import com.facebook.react.bridge.ReactApplicationContext; 4 | import com.facebook.react.bridge.ReactContextBaseJavaModule; 5 | import com.facebook.react.bridge.ReactMethod; 6 | import com.facebook.react.bridge.Promise; 7 | 8 | public class SubstrateSignModule extends ReactContextBaseJavaModule { 9 | 10 | private final ReactApplicationContext reactContext; 11 | 12 | static { 13 | System.loadLibrary("signer"); 14 | } 15 | 16 | public SubstrateSignModule(ReactApplicationContext reactContext) { 17 | super(reactContext); 18 | this.reactContext = reactContext; 19 | } 20 | 21 | private void rejectWithException(Promise promise, String code, Exception e) { 22 | String[] sp = e.getMessage().split(": "); 23 | String s = sp[sp.length - 1].trim().replace("\"", ""); 24 | promise.reject(code, s); 25 | } 26 | 27 | @Override 28 | public String getName() { 29 | return "SubstrateSign"; 30 | } 31 | 32 | @ReactMethod 33 | public void brainWalletAddress(String seed, Promise promise) { 34 | promise.resolve(ethkeyBrainwalletAddress(seed)); 35 | } 36 | 37 | @ReactMethod 38 | public void brainWalletBIP39Address(String seed, Promise promise) { 39 | try { 40 | promise.resolve(ethkeyBrainwalletBIP39Address(seed)); 41 | } catch (Exception e) { 42 | rejectWithException(promise, "brainwallet bip39 address", e); 43 | } 44 | } 45 | 46 | @ReactMethod 47 | public void brainWalletSign(String seed, String message, Promise promise) { 48 | try { 49 | promise.resolve(ethkeyBrainwalletSign(seed, message)); 50 | } catch (Exception e) { 51 | rejectWithException(promise, "brainwallet sign", e); 52 | } 53 | } 54 | 55 | @ReactMethod 56 | public void rlpItem(String rlp, int position, Promise promise) { 57 | try { 58 | promise.resolve(ethkeyRlpItem(rlp, position)); 59 | } catch (Exception e) { 60 | rejectWithException(promise, "rlp item", e); 61 | } 62 | } 63 | 64 | @ReactMethod 65 | public void keccak(String data, Promise promise) { 66 | try { 67 | promise.resolve(ethkeyKeccak(data)); 68 | } catch (Exception e) { 69 | rejectWithException(promise, "keccak", e); 70 | } 71 | } 72 | 73 | @ReactMethod 74 | public void blake2b(String data, Promise promise) { 75 | try { 76 | promise.resolve(ethkeyBlake(data)); 77 | } catch (Exception e) { 78 | rejectWithException(promise, "blake2b", e); 79 | } 80 | } 81 | 82 | @ReactMethod 83 | public void ethSign(String data, Promise promise) { 84 | promise.resolve(ethkeyEthSign(data)); 85 | } 86 | 87 | @ReactMethod 88 | public void blockiesIcon(String seed, Promise promise) { 89 | promise.resolve(ethkeyBlockiesIcon(seed)); 90 | } 91 | 92 | @ReactMethod 93 | public void randomPhrase(int wordsNumber, Promise promise) { 94 | promise.resolve(ethkeyRandomPhrase(wordsNumber)); 95 | } 96 | 97 | @ReactMethod 98 | public void encryptData(String data, String password, Promise promise) { 99 | promise.resolve(ethkeyEncryptData(data, password)); 100 | } 101 | 102 | @ReactMethod 103 | public void decryptData(String data, String password, Promise promise) { 104 | try { 105 | promise.resolve(ethkeyDecryptData(data, password)); 106 | } catch (Exception e) { 107 | rejectWithException(promise, "decrypt data", e); 108 | } 109 | } 110 | 111 | @ReactMethod 112 | public void qrCode(String data, Promise promise) { 113 | try { 114 | promise.resolve(ethkeyQrCode(data)); 115 | } catch (Exception e) { 116 | rejectWithException(promise, "qr code", e); 117 | } 118 | } 119 | 120 | @ReactMethod 121 | public void qrCodeHex(String data, Promise promise) { 122 | try { 123 | promise.resolve(ethkeyQrCodeHex(data)); 124 | } catch (Exception e) { 125 | rejectWithException(promise, "qr code hex", e); 126 | } 127 | } 128 | 129 | @ReactMethod 130 | public void substrateAddress(String seed, int prefix, Promise promise) { 131 | try { 132 | promise.resolve(substrateBrainwalletAddress(seed, prefix)); 133 | } catch (Exception e) { 134 | rejectWithException(promise, "substrate address", e); 135 | } 136 | } 137 | 138 | @ReactMethod 139 | public void substrateSign(String seed, String message, Promise promise) { 140 | try { 141 | promise.resolve(substrateBrainwalletSign(seed, message)); 142 | } catch (Exception e) { 143 | rejectWithException(promise, "substrate sign", e); 144 | } 145 | } 146 | 147 | @ReactMethod 148 | public void schnorrkelVerify(String seed, String message, String signature, Promise promise) { 149 | try { 150 | promise.resolve(schnorrkelVerify(seed, message, signature)); 151 | } catch (Exception e) { 152 | rejectWithException(promise, "schnorrkel verify", e); 153 | } 154 | } 155 | 156 | @ReactMethod 157 | public void decryptDataRef(String data, String password, Promise promise) { 158 | try { 159 | // `long` is incompatible with the bridge so pass as a double 160 | double d = Double.longBitsToDouble(ethkeyDecryptDataRef(data, password)); 161 | if (Double.isNaN(d)) { 162 | promise.reject("reference is nan", "reference is nan"); 163 | } else { 164 | promise.resolve(d); 165 | } 166 | } catch (Exception e) { 167 | rejectWithException(promise, "decrypt data ref", e); 168 | } 169 | } 170 | 171 | @ReactMethod 172 | public void destroyDataRef(double data_ref, Promise promise) { 173 | try { 174 | ethkeyDestroyDataRef(Double.doubleToRawLongBits(data_ref)); 175 | promise.resolve(0); 176 | } catch (Exception e) { 177 | rejectWithException(promise, "destroy data ref", e); 178 | } 179 | } 180 | 181 | @ReactMethod 182 | public void brainWalletSignWithRef(double seed_ref, String message, Promise promise) { 183 | try { 184 | promise.resolve(ethkeyBrainwalletSignWithRef(Double.doubleToRawLongBits(seed_ref), message)); 185 | } catch (Exception e) { 186 | rejectWithException(promise, "brainwallet sign with ref", e); 187 | } 188 | } 189 | 190 | @ReactMethod 191 | public void substrateSignWithRef(double seed_ref, String suriSuffix, String message, Promise promise) { 192 | try { 193 | String s = ethkeySubstrateBrainwalletSignWithRef(Double.doubleToRawLongBits(seed_ref), suriSuffix, message); 194 | promise.resolve(s); 195 | } catch (Exception e) { 196 | rejectWithException(promise, "substrate sign with ref", e); 197 | } 198 | } 199 | 200 | @ReactMethod 201 | public void brainWalletAddressWithRef(double seedRef, Promise promise) { 202 | try { 203 | String s = ethkeyBrainWalletAddressWithRef(Double.doubleToRawLongBits(seedRef)); 204 | promise.resolve(s); 205 | } catch (Exception e) { 206 | rejectWithException(promise, "brainwallet address with ref", e); 207 | } 208 | } 209 | 210 | @ReactMethod 211 | public void substrateAddressWithRef(double seedRef, String suriSuffix, int prefix, Promise promise) { 212 | try { 213 | String substrateAddress = ethkeySubstrateWalletAddressWithRef(Double.doubleToRawLongBits(seedRef), suriSuffix, prefix); 214 | promise.resolve(substrateAddress); 215 | } catch (Exception e) { 216 | rejectWithException(promise, "substrate address with ref", e); 217 | } 218 | } 219 | 220 | @ReactMethod 221 | public void substrateSecretWithRef(double seedRef, String suriSuffix, Promise promise) { 222 | try { 223 | String derivedSubstrateSecret = ethkeySubstrateMiniSecretKeyWithRef(Double.doubleToRawLongBits(seedRef), suriSuffix); 224 | promise.resolve(derivedSubstrateSecret); 225 | } catch (Exception e) { 226 | rejectWithException(promise, "substrate secret", e); 227 | } 228 | } 229 | 230 | @ReactMethod 231 | public void substrateSecret(String suri, Promise promise) { 232 | try { 233 | String derivedSubstrateSecret = ethkeySubstrateMiniSecretKey(suri); 234 | promise.resolve(derivedSubstrateSecret); 235 | } catch (Exception e) { 236 | rejectWithException(promise, "substrate secret with ref", e); 237 | } 238 | } 239 | 240 | private static native String ethkeyBrainwalletAddress(String seed); 241 | private static native String ethkeyBrainwalletBIP39Address(String seed); 242 | private static native String ethkeyBrainwalletSign(String seed, String message); 243 | private static native String ethkeyRlpItem(String data, int position); 244 | private static native String ethkeyKeccak(String data); 245 | private static native String ethkeyBlake(String data); 246 | private static native String ethkeyEthSign(String data); 247 | private static native String ethkeyBlockiesIcon(String seed); 248 | private static native String ethkeyRandomPhrase(int wordsNumber); 249 | private static native String ethkeyEncryptData(String data, String password); 250 | private static native String ethkeyDecryptData(String data, String password); 251 | private static native String ethkeyQrCode(String data); 252 | private static native String ethkeyQrCodeHex(String data); 253 | private static native String substrateBrainwalletAddress(String seed, int prefix); 254 | private static native String substrateBrainwalletSign(String seed, String message); 255 | private static native boolean schnorrkelVerify(String seed, String message, String signature); 256 | private static native long ethkeyDecryptDataRef(String data, String password); 257 | private static native void ethkeyDestroyDataRef(long data_ref); 258 | private static native String ethkeyBrainwalletSignWithRef(long seed_ref, String message); 259 | private static native String ethkeySubstrateBrainwalletSignWithRef(long seed_ref, String suriSuffix, String message); 260 | private static native String ethkeySubstrateWalletAddressWithRef(long seedRef, String suriSuffix, int prefix); 261 | private static native String ethkeyBrainWalletAddressWithRef(long seedRef); 262 | private static native String ethkeySubstrateMiniSecretKey(String suri); 263 | private static native String ethkeySubstrateMiniSecretKeyWithRef(long seedRef, String suriSuffix); 264 | } 265 | -------------------------------------------------------------------------------- /android/src/main/java/io/parity/substrateSign/SubstrateSignPackage.java: -------------------------------------------------------------------------------- 1 | package io.parity.substrateSign; 2 | 3 | import java.util.Arrays; 4 | import java.util.Collections; 5 | import java.util.List; 6 | 7 | import com.facebook.react.ReactPackage; 8 | import com.facebook.react.bridge.NativeModule; 9 | import com.facebook.react.bridge.ReactApplicationContext; 10 | import com.facebook.react.uimanager.ViewManager; 11 | import com.facebook.react.bridge.JavaScriptModule; 12 | 13 | public class SubstrateSignPackage implements ReactPackage { 14 | @Override 15 | public List createNativeModules(ReactApplicationContext reactContext) { 16 | return Arrays.asList(new SubstrateSignModule(reactContext)); 17 | } 18 | 19 | @Override 20 | public List createViewManagers(ReactApplicationContext reactContext) { 21 | return Collections.emptyList(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /android/src/main/jniLibs/arm64-v8a/libsigner.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paritytech/react-native-substrate-sign/9b1043bf2ebf52b97a5c1f9e68ed41048263f82b/android/src/main/jniLibs/arm64-v8a/libsigner.so -------------------------------------------------------------------------------- /android/src/main/jniLibs/armeabi-v7a/libsigner.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paritytech/react-native-substrate-sign/9b1043bf2ebf52b97a5c1f9e68ed41048263f82b/android/src/main/jniLibs/armeabi-v7a/libsigner.so -------------------------------------------------------------------------------- /android/src/main/jniLibs/x86/libsigner.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paritytech/react-native-substrate-sign/9b1043bf2ebf52b97a5c1f9e68ed41048263f82b/android/src/main/jniLibs/x86/libsigner.so -------------------------------------------------------------------------------- /android/src/main/jniLibs/x86_64/libsigner.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paritytech/react-native-substrate-sign/9b1043bf2ebf52b97a5c1f9e68ed41048263f82b/android/src/main/jniLibs/x86_64/libsigner.so -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'react-native-substrate-sign' { 2 | 3 | export function brainWalletAddress(seed: string): Promise; 4 | 5 | export function brainWalletBIP39Address(seed: string): Promise; 6 | 7 | export function brainWalletSign(seed: string, message: string): Promise; 8 | 9 | export function rlpItem(rlp: string, position: number): Promise; 10 | 11 | export function keccak(data: string): Promise; 12 | 13 | export function blake2b(data: string): Promise; 14 | 15 | export function ethSign(data: string): Promise; 16 | 17 | export function blockiesIcon(seed: string): Promise; 18 | 19 | export function randomPhrase(wordsNumber: number): Promise; 20 | 21 | export function encryptData(data: string, password: string): Promise; 22 | 23 | export function decryptData(data: string, password: string): Promise; 24 | 25 | export function qrCode(data: string): Promise; 26 | 27 | export function qrCodeHex(data: string): Promise; 28 | 29 | export function substrateAddress(seed: string, prefix: number): Promise; 30 | 31 | export function substrateSign(seed: string, message: string): Promise; 32 | 33 | export function schnorrkelVerify(seed: string, message: string, signature: string): Promise; 34 | 35 | export function decryptDataRef(data: string, password: string): Promise; 36 | 37 | export function destroyDataRef(dataRef: number): Promise; 38 | 39 | export function brainWalletSignWithRef(dataRef: number, message: string): Promise; 40 | 41 | export function substrateSignWithRef(dataRef: number, suriSuffix: string, message: string): Promise; 42 | 43 | export function brainWalletAddressWithRef(dataRef: number): Promise; 44 | 45 | export function substrateAddressWithRef(dataRef: number, suriSuffix: string, prefix: number): Promise; 46 | 47 | export function substrateSecret(suri: string): Promise; 48 | 49 | export function substrateSecretWithRef(dataRef: number, suriSuffix: string): Promise; 50 | } 51 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import { NativeModules } from 'react-native'; 2 | 3 | const { SubstrateSign } = NativeModules; 4 | 5 | export default SubstrateSign; 6 | -------------------------------------------------------------------------------- /ios/SubstrateSign-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2020 Parity Technologies (UK) Ltd. 2 | // This file is part of Parity. 3 | 4 | // Parity is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | 9 | // Parity is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | 14 | // You should have received a copy of the GNU General Public License 15 | // along with Parity. If not, see . 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 "signer.h" 23 | -------------------------------------------------------------------------------- /ios/SubstrateSign.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface SubstrateSign : NSObject 4 | 5 | @end 6 | -------------------------------------------------------------------------------- /ios/SubstrateSign.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface RCT_EXTERN_MODULE(SubstrateSign, NSObject) 4 | 5 | // explanation about threading here: https://stackoverflow.com/a/50775641/3060739 6 | - (dispatch_queue_t)methodQueue 7 | { 8 | return dispatch_get_main_queue(); 9 | } 10 | 11 | + (BOOL)requiresMainQueueSetup 12 | { 13 | return YES; 14 | } 15 | 16 | RCT_EXTERN_METHOD(brainWalletAddress:(NSString*)seed resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) 17 | RCT_EXTERN_METHOD(brainWalletSecret:(NSString*)seed resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) 18 | RCT_EXTERN_METHOD(brainWalletSign:(NSString*)seed message:(NSString*)message resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) 19 | RCT_EXTERN_METHOD(rlpItem:(NSString*)rlp position:(NSUInteger)position resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) 20 | RCT_EXTERN_METHOD(keccak:(NSString*)data resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) 21 | RCT_EXTERN_METHOD(ethSign:(NSString*)data resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) 22 | RCT_EXTERN_METHOD(blockiesIcon:(NSString*)seed resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) 23 | RCT_EXTERN_METHOD(randomPhrase:(NSInteger*)wordsNumber resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) 24 | RCT_EXTERN_METHOD(encryptData:(NSString*)data password:(NSString*)password resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) 25 | RCT_EXTERN_METHOD(decryptData:(NSString*)data password:(NSString*)password resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) 26 | RCT_EXTERN_METHOD(qrCode:(NSString*)data resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) 27 | RCT_EXTERN_METHOD(qrCodeHex:(NSString*)data resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) 28 | RCT_EXTERN_METHOD(substrateAddress:(NSString*)seed prefix:(NSUInteger*)prefix resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) 29 | RCT_EXTERN_METHOD(substrateSign:(NSString*)seed message:(NSString*)message resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) 30 | RCT_EXTERN_METHOD(blake2b:(NSString*)data resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) 31 | RCT_EXTERN_METHOD(schnorrkelVerify: (NSString*)seed message:(NSString*)message signature:(NSString*)signature resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) 32 | RCT_EXTERN_METHOD(decryptDataRef:(NSString*)data password:(NSString*)password resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) 33 | RCT_EXTERN_METHOD(destroyDataRef:(int64_t)dataRef resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) 34 | RCT_EXTERN_METHOD(brainWalletSignWithRef:(int64_t)seedRef message:(NSString*)message resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) 35 | RCT_EXTERN_METHOD(substrateSignWithRef:(int64_t)seedRef suri_suffix:(NSString*)suri_suffix message:(NSString*)message resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) 36 | RCT_EXTERN_METHOD(substrateAddressWithRef:(int64_t)seedRef suri_suffix:(NSString*)suri_suffix prefix:(NSUInteger*)prefix resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) 37 | RCT_EXTERN_METHOD(brainWalletAddressWithRef:(int64_t)seedRef resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) 38 | RCT_EXTERN_METHOD(substrateSecret:(NSString*)suri resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) 39 | RCT_EXTERN_METHOD(substrateSecretWithRef:(int64_t*)seedRef suri_suffix:(NSString*)suri_suffix resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) 40 | @end 41 | -------------------------------------------------------------------------------- /ios/SubstrateSign.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | func handle_error( 4 | resolve: RCTPromiseResolveBlock, 5 | reject: RCTPromiseRejectBlock, 6 | get_result: (UnsafeMutablePointer) -> T, 7 | success: (T) -> U 8 | ) -> Void { 9 | var err = ExternError() 10 | let err_ptr: UnsafeMutablePointer = UnsafeMutablePointer(&err) 11 | let res = get_result(err_ptr) 12 | if err_ptr.pointee.code == 0 { 13 | resolve(success(res)) 14 | } else { 15 | let val = String(cString: err_ptr.pointee.message) 16 | signer_destroy_string(err_ptr.pointee.message) 17 | reject(String(describing: err_ptr.pointee.code), val, nil) 18 | } 19 | } 20 | 21 | @objc(SubstrateSign) 22 | class SubstrateSign: NSObject { 23 | 24 | public static func requiresMainQueueSetup() -> Bool { 25 | return true; 26 | } 27 | 28 | @objc func brainWalletAddress(_ seed: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void { 29 | handle_error( 30 | resolve: resolve, 31 | reject: reject, 32 | get_result: { ethkey_brainwallet_address($0, seed) }, 33 | success: { (res: Optional>) -> String in 34 | let val = String(cString: res!) 35 | signer_destroy_string(res!) 36 | return val 37 | }) 38 | } 39 | 40 | @objc func brainWalletSign(_ seed: String, message: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void { 41 | handle_error( 42 | resolve: resolve, 43 | reject: reject, 44 | get_result: { ethkey_brainwallet_sign($0, seed, message) }, 45 | success: { (res: Optional>) -> String in 46 | let val = String(cString: res!) 47 | signer_destroy_string(res!) 48 | return val 49 | }) 50 | } 51 | 52 | @objc func rlpItem(_ rlp: String, position: UInt32, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void { 53 | handle_error( 54 | resolve: resolve, 55 | reject: reject, 56 | get_result: { rlp_item($0, rlp, position) }, 57 | success: { (res: Optional>) -> String in 58 | let val = String(cString: res!) 59 | signer_destroy_string(res!) 60 | return val 61 | }) 62 | } 63 | 64 | @objc func keccak(_ data: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void { 65 | handle_error( 66 | resolve: resolve, 67 | reject: reject, 68 | get_result: { keccak256($0, data) }, 69 | success: { (res: Optional>) -> String in 70 | let val = String(cString: res!) 71 | signer_destroy_string(res!) 72 | return val 73 | }) 74 | } 75 | 76 | @objc func blake2b(_ data: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void { 77 | handle_error( 78 | resolve: resolve, 79 | reject: reject, 80 | get_result: { blake($0, data) }, 81 | success: { (res: Optional>) -> String in 82 | let val = String(cString: res!) 83 | signer_destroy_string(res!) 84 | return val 85 | }) 86 | } 87 | 88 | @objc func ethSign(_ data: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void { 89 | handle_error( 90 | resolve: resolve, 91 | reject: reject, 92 | get_result: { eth_sign($0, data) }, 93 | success: { (res: Optional>) -> String in 94 | let val = String(cString: res!) 95 | signer_destroy_string(res!) 96 | return val 97 | }) 98 | } 99 | 100 | @objc func blockiesIcon(_ seed: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void { 101 | handle_error( 102 | resolve: resolve, 103 | reject: reject, 104 | get_result: { blockies_icon($0, seed) }, 105 | success: { (res: Optional>) -> String in 106 | let val = String(cString: res!) 107 | signer_destroy_string(res!) 108 | return val 109 | }) 110 | } 111 | 112 | @objc func randomPhrase(_ wordsNumber:NSInteger, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void { 113 | handle_error( 114 | resolve: resolve, 115 | reject: reject, 116 | get_result: { random_phrase($0, Int32(wordsNumber)) }, 117 | success: { (res: Optional>) -> String in 118 | let val = String(cString: res!) 119 | signer_destroy_string(res!) 120 | return val 121 | }) 122 | } 123 | 124 | @objc func encryptData(_ data: String, password: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void { 125 | handle_error( 126 | resolve: resolve, 127 | reject: reject, 128 | get_result: { encrypt_data($0, data, password) }, 129 | success: { (res: Optional>) -> String in 130 | let val = String(cString: res!) 131 | signer_destroy_string(res!) 132 | return val 133 | }) 134 | } 135 | 136 | @objc func decryptData(_ data: String, password: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void { 137 | handle_error( 138 | resolve: resolve, 139 | reject: reject, 140 | get_result: { decrypt_data($0, data, password) }, 141 | success: { (res: Optional>) -> String in 142 | let val = String(cString: res!) 143 | signer_destroy_string(res!) 144 | return val 145 | }) 146 | } 147 | 148 | @objc func qrCode(_ data: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void { 149 | handle_error( 150 | resolve: resolve, 151 | reject: reject, 152 | get_result: { qrcode($0, data) }, 153 | success: { (res: Optional>) -> String in 154 | let val = String(cString: res!) 155 | signer_destroy_string(res!) 156 | return val 157 | }) 158 | } 159 | 160 | @objc func qrCodeHex(_ data: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void { 161 | handle_error( 162 | resolve: resolve, 163 | reject: reject, 164 | get_result: { qrcode_hex($0, data) }, 165 | success: { (res: Optional>) -> String in 166 | let val = String(cString: res!) 167 | signer_destroy_string(res!) 168 | return val 169 | }) 170 | } 171 | 172 | @objc func substrateAddress(_ seed: String, prefix: UInt32, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void { 173 | handle_error( 174 | resolve: resolve, 175 | reject: reject, 176 | get_result: { substrate_brainwallet_address($0, seed, prefix) }, 177 | success: { (res: Optional>) -> String in 178 | let val = String(cString: res!) 179 | signer_destroy_string(res!) 180 | return val 181 | }) 182 | } 183 | 184 | @objc func substrateSign(_ seed: String, message: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void { 185 | handle_error( 186 | resolve: resolve, 187 | reject: reject, 188 | get_result: { substrate_brainwallet_sign($0, seed, message) }, 189 | success: { (res: Optional>) -> String in 190 | let val = String(cString: res!) 191 | signer_destroy_string(res!) 192 | return val 193 | }) 194 | } 195 | 196 | @objc func schnorrkelVerify(_ seed: String, message: String, signature: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void { 197 | handle_error( 198 | resolve: resolve, 199 | reject: reject, 200 | get_result: { schnorrkel_verify($0, seed, message, signature) }, 201 | // return a bool. no cleanup 202 | success: { return $0 }) 203 | } 204 | 205 | @objc func decryptDataRef(_ data: String, password: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void { 206 | handle_error( 207 | resolve: resolve, 208 | reject: reject, 209 | get_result: { decrypt_data_ref($0, data, password) }, 210 | // return a long. no cleanup 211 | success: { return $0 }) 212 | } 213 | 214 | @objc func destroyDataRef(_ data_ref: Int64, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void { 215 | handle_error( 216 | resolve: resolve, 217 | reject: reject, 218 | get_result: { destroy_data_ref($0, data_ref) }, 219 | // return zero. no cleanup 220 | success: { return 0 }) 221 | } 222 | 223 | @objc func brainWalletSignWithRef(_ seed_ref: Int64, message: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void { 224 | handle_error( 225 | resolve: resolve, 226 | reject: reject, 227 | get_result: { ethkey_brainwallet_sign_with_ref($0, seed_ref, message) }, 228 | success: { (res: Optional>) -> String in 229 | let val = String(cString: res!) 230 | signer_destroy_string(res!) 231 | return val 232 | }) 233 | } 234 | 235 | @objc func substrateSignWithRef(_ seed_ref: Int64, suri_suffix: String, message: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void { 236 | handle_error( 237 | resolve: resolve, 238 | reject: reject, 239 | get_result: { substrate_brainwallet_sign_with_ref($0, seed_ref, suri_suffix, message) }, 240 | success: { (res: Optional>) -> String in 241 | let val = String(cString: res!) 242 | signer_destroy_string(res!) 243 | return val 244 | }) 245 | } 246 | 247 | @objc func brainWalletAddressWithRef(_ seed_ref: Int64, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void { 248 | handle_error( 249 | resolve: resolve, 250 | reject: reject, 251 | get_result: { brain_wallet_address_with_ref($0, seed_ref) }, 252 | success: { (res: Optional>) -> String in 253 | let val = String(cString: res!) 254 | signer_destroy_string(res!) 255 | return val 256 | }) 257 | } 258 | 259 | @objc func substrateAddressWithRef(_ seed_ref: Int64, suri_suffix: String, prefix: UInt32, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void { 260 | handle_error( 261 | resolve: resolve, 262 | reject: reject, 263 | get_result: { substrate_address_with_ref($0, seed_ref, suri_suffix, prefix) }, 264 | success: { (res: Optional>) -> String in 265 | let val = String(cString: res!) 266 | signer_destroy_string(res!) 267 | return val 268 | }) 269 | } 270 | 271 | @objc func substrateSecret(_ suri: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void { 272 | handle_error( 273 | resolve: resolve, 274 | reject: reject, 275 | get_result: { substrate_mini_secret_key($0, suri) }, 276 | success: { (res: Optional>) -> String in 277 | let val = String(cString: res!) 278 | signer_destroy_string(res!) 279 | return val 280 | }) 281 | } 282 | 283 | @objc func substrateSecretWithRef(_ seed_ref: Int64, suri_suffix: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void { 284 | handle_error( 285 | resolve: resolve, 286 | reject: reject, 287 | get_result: { substrate_mini_secret_key_with_ref($0, seed_ref, suri_suffix) }, 288 | success: { (res: Optional>) -> String in 289 | let val = String(cString: res!) 290 | signer_destroy_string(res!) 291 | return val 292 | }) 293 | } 294 | } 295 | 296 | -------------------------------------------------------------------------------- /ios/SubstrateSign.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 6784635124ADE8D3000990D6 /* libsigner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6784635024ADE8D3000990D6 /* libsigner.a */; }; 11 | 6784635424ADF355000990D6 /* libSubstrateSign.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 134814201AA4EA6300B7C361 /* libSubstrateSign.a */; }; 12 | 67E5C7DF247AC14D00801670 /* libresolv.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 67E5C7DE247AC14D00801670 /* libresolv.tbd */; }; 13 | /* End PBXBuildFile section */ 14 | 15 | /* Begin PBXCopyFilesBuildPhase section */ 16 | 58B511D91A9E6C8500147676 /* CopyFiles */ = { 17 | isa = PBXCopyFilesBuildPhase; 18 | buildActionMask = 2147483647; 19 | dstPath = "include/$(PRODUCT_NAME)"; 20 | dstSubfolderSpec = 16; 21 | files = ( 22 | ); 23 | runOnlyForDeploymentPostprocessing = 0; 24 | }; 25 | /* End PBXCopyFilesBuildPhase section */ 26 | 27 | /* Begin PBXFileReference section */ 28 | 134814201AA4EA6300B7C361 /* libSubstrateSign.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSubstrateSign.a; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | 6784635024ADE8D3000990D6 /* libsigner.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libsigner.a; sourceTree = ""; }; 30 | 67E5C7DE247AC14D00801670 /* libresolv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libresolv.tbd; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/usr/lib/libresolv.tbd; sourceTree = DEVELOPER_DIR; }; 31 | /* End PBXFileReference section */ 32 | 33 | /* Begin PBXFrameworksBuildPhase section */ 34 | 58B511D81A9E6C8500147676 /* Frameworks */ = { 35 | isa = PBXFrameworksBuildPhase; 36 | buildActionMask = 2147483647; 37 | files = ( 38 | 6784635124ADE8D3000990D6 /* libsigner.a in Frameworks */, 39 | 67E5C7DF247AC14D00801670 /* libresolv.tbd in Frameworks */, 40 | 6784635424ADF355000990D6 /* libSubstrateSign.a in Frameworks */, 41 | ); 42 | runOnlyForDeploymentPostprocessing = 0; 43 | }; 44 | /* End PBXFrameworksBuildPhase section */ 45 | 46 | /* Begin PBXGroup section */ 47 | 134814211AA4EA7D00B7C361 /* Products */ = { 48 | isa = PBXGroup; 49 | children = ( 50 | 134814201AA4EA6300B7C361 /* libSubstrateSign.a */, 51 | ); 52 | name = Products; 53 | sourceTree = ""; 54 | }; 55 | 58B511D21A9E6C8500147676 = { 56 | isa = PBXGroup; 57 | children = ( 58 | 134814211AA4EA7D00B7C361 /* Products */, 59 | 675298932476D5BE00387331 /* Frameworks */, 60 | ); 61 | sourceTree = ""; 62 | }; 63 | 675298932476D5BE00387331 /* Frameworks */ = { 64 | isa = PBXGroup; 65 | children = ( 66 | 6784635024ADE8D3000990D6 /* libsigner.a */, 67 | 67E5C7DE247AC14D00801670 /* libresolv.tbd */, 68 | ); 69 | name = Frameworks; 70 | sourceTree = ""; 71 | }; 72 | /* End PBXGroup section */ 73 | 74 | /* Begin PBXNativeTarget section */ 75 | 58B511DA1A9E6C8500147676 /* SubstrateSign */ = { 76 | isa = PBXNativeTarget; 77 | buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "SubstrateSign" */; 78 | buildPhases = ( 79 | 58B511D71A9E6C8500147676 /* Sources */, 80 | 58B511D81A9E6C8500147676 /* Frameworks */, 81 | 58B511D91A9E6C8500147676 /* CopyFiles */, 82 | ); 83 | buildRules = ( 84 | ); 85 | dependencies = ( 86 | ); 87 | name = SubstrateSign; 88 | productName = RCTDataManager; 89 | productReference = 134814201AA4EA6300B7C361 /* libSubstrateSign.a */; 90 | productType = "com.apple.product-type.library.static"; 91 | }; 92 | /* End PBXNativeTarget section */ 93 | 94 | /* Begin PBXProject section */ 95 | 58B511D31A9E6C8500147676 /* Project object */ = { 96 | isa = PBXProject; 97 | attributes = { 98 | LastUpgradeCheck = 0920; 99 | ORGANIZATIONNAME = Facebook; 100 | TargetAttributes = { 101 | 58B511DA1A9E6C8500147676 = { 102 | CreatedOnToolsVersion = 6.1.1; 103 | LastSwiftMigration = 1150; 104 | }; 105 | }; 106 | }; 107 | buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "SubstrateSign" */; 108 | compatibilityVersion = "Xcode 3.2"; 109 | developmentRegion = en; 110 | hasScannedForEncodings = 0; 111 | knownRegions = ( 112 | en, 113 | Base, 114 | ); 115 | mainGroup = 58B511D21A9E6C8500147676; 116 | productRefGroup = 58B511D21A9E6C8500147676; 117 | projectDirPath = ""; 118 | projectRoot = ""; 119 | targets = ( 120 | 58B511DA1A9E6C8500147676 /* SubstrateSign */, 121 | ); 122 | }; 123 | /* End PBXProject section */ 124 | 125 | /* Begin PBXSourcesBuildPhase section */ 126 | 58B511D71A9E6C8500147676 /* Sources */ = { 127 | isa = PBXSourcesBuildPhase; 128 | buildActionMask = 2147483647; 129 | files = ( 130 | ); 131 | runOnlyForDeploymentPostprocessing = 0; 132 | }; 133 | /* End PBXSourcesBuildPhase section */ 134 | 135 | /* Begin XCBuildConfiguration section */ 136 | 58B511ED1A9E6C8500147676 /* Debug */ = { 137 | isa = XCBuildConfiguration; 138 | buildSettings = { 139 | ALWAYS_SEARCH_USER_PATHS = NO; 140 | CLANG_ANALYZER_NONNULL = YES; 141 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 142 | CLANG_CXX_LIBRARY = "libc++"; 143 | CLANG_ENABLE_MODULES = YES; 144 | CLANG_ENABLE_OBJC_ARC = YES; 145 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 146 | CLANG_WARN_BOOL_CONVERSION = YES; 147 | CLANG_WARN_COMMA = YES; 148 | CLANG_WARN_CONSTANT_CONVERSION = YES; 149 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 150 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 151 | CLANG_WARN_EMPTY_BODY = YES; 152 | CLANG_WARN_ENUM_CONVERSION = YES; 153 | CLANG_WARN_INFINITE_RECURSION = YES; 154 | CLANG_WARN_INT_CONVERSION = YES; 155 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 156 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 157 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 158 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 159 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 160 | CLANG_WARN_STRICT_PROTOTYPES = YES; 161 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 162 | CLANG_WARN_UNREACHABLE_CODE = YES; 163 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 164 | COPY_PHASE_STRIP = NO; 165 | ENABLE_BITCODE = NO; 166 | ENABLE_STRICT_OBJC_MSGSEND = YES; 167 | ENABLE_TESTABILITY = YES; 168 | GCC_C_LANGUAGE_STANDARD = gnu99; 169 | GCC_DYNAMIC_NO_PIC = NO; 170 | GCC_NO_COMMON_BLOCKS = YES; 171 | GCC_OPTIMIZATION_LEVEL = 0; 172 | GCC_PREPROCESSOR_DEFINITIONS = ( 173 | "DEBUG=1", 174 | "$(inherited)", 175 | ); 176 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 177 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 178 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 179 | GCC_WARN_UNDECLARED_SELECTOR = YES; 180 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 181 | GCC_WARN_UNUSED_FUNCTION = YES; 182 | GCC_WARN_UNUSED_VARIABLE = YES; 183 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 184 | LD_RUNPATH_SEARCH_PATHS = "/usr/lib/swift $(inherited)"; 185 | LIBRARY_SEARCH_PATHS = ( 186 | "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"", 187 | "\"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)\"", 188 | "\"$(inherited)\"", 189 | "$(PROJECT_DIR)", 190 | ); 191 | MTL_ENABLE_DEBUG_INFO = YES; 192 | ONLY_ACTIVE_ARCH = NO; 193 | SDKROOT = iphoneos; 194 | VALID_ARCHS = "arm64 arm64e armv7 armv7s x86_64"; 195 | }; 196 | name = Debug; 197 | }; 198 | 58B511EE1A9E6C8500147676 /* Release */ = { 199 | isa = XCBuildConfiguration; 200 | buildSettings = { 201 | ALWAYS_SEARCH_USER_PATHS = NO; 202 | CLANG_ANALYZER_NONNULL = YES; 203 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 204 | CLANG_CXX_LIBRARY = "libc++"; 205 | CLANG_ENABLE_MODULES = YES; 206 | CLANG_ENABLE_OBJC_ARC = YES; 207 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 208 | CLANG_WARN_BOOL_CONVERSION = YES; 209 | CLANG_WARN_COMMA = YES; 210 | CLANG_WARN_CONSTANT_CONVERSION = YES; 211 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 212 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 213 | CLANG_WARN_EMPTY_BODY = YES; 214 | CLANG_WARN_ENUM_CONVERSION = YES; 215 | CLANG_WARN_INFINITE_RECURSION = YES; 216 | CLANG_WARN_INT_CONVERSION = YES; 217 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 218 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 219 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 220 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 221 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 222 | CLANG_WARN_STRICT_PROTOTYPES = YES; 223 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 224 | CLANG_WARN_UNREACHABLE_CODE = YES; 225 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 226 | COPY_PHASE_STRIP = YES; 227 | ENABLE_BITCODE = NO; 228 | ENABLE_NS_ASSERTIONS = NO; 229 | ENABLE_STRICT_OBJC_MSGSEND = YES; 230 | GCC_C_LANGUAGE_STANDARD = gnu99; 231 | GCC_NO_COMMON_BLOCKS = YES; 232 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 233 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 234 | GCC_WARN_UNDECLARED_SELECTOR = YES; 235 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 236 | GCC_WARN_UNUSED_FUNCTION = YES; 237 | GCC_WARN_UNUSED_VARIABLE = YES; 238 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 239 | LD_RUNPATH_SEARCH_PATHS = "/usr/lib/swift $(inherited)"; 240 | LIBRARY_SEARCH_PATHS = ( 241 | "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"", 242 | "\"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)\"", 243 | "\"$(inherited)\"", 244 | "$(PROJECT_DIR)", 245 | ); 246 | MTL_ENABLE_DEBUG_INFO = NO; 247 | SDKROOT = iphoneos; 248 | VALIDATE_PRODUCT = YES; 249 | VALID_ARCHS = "arm64 arm64e armv7 armv7s x86_64"; 250 | }; 251 | name = Release; 252 | }; 253 | 58B511F01A9E6C8500147676 /* Debug */ = { 254 | isa = XCBuildConfiguration; 255 | buildSettings = { 256 | CLANG_ENABLE_MODULES = YES; 257 | HEADER_SEARCH_PATHS = ( 258 | "$(inherited)", 259 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 260 | "$(SRCROOT)/../../../React/**", 261 | "$(SRCROOT)/../../react-native/React/**", 262 | "$(SRCROOT)", 263 | ); 264 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 265 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 266 | LIBRARY_SEARCH_PATHS = ( 267 | "$(SRCROOT)", 268 | "$(inherited)", 269 | ); 270 | ONLY_ACTIVE_ARCH = NO; 271 | OTHER_LDFLAGS = "-ObjC"; 272 | PRODUCT_NAME = SubstrateSign; 273 | SKIP_INSTALL = YES; 274 | SWIFT_OBJC_BRIDGING_HEADER = "SubstrateSign-Bridging-Header.h"; 275 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 276 | SWIFT_VERSION = 5.0; 277 | }; 278 | name = Debug; 279 | }; 280 | 58B511F11A9E6C8500147676 /* Release */ = { 281 | isa = XCBuildConfiguration; 282 | buildSettings = { 283 | CLANG_ENABLE_MODULES = YES; 284 | HEADER_SEARCH_PATHS = ( 285 | "$(inherited)", 286 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 287 | "$(SRCROOT)/../../../React/**", 288 | "$(SRCROOT)/../../react-native/React/**", 289 | "$(SRCROOT)", 290 | ); 291 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 292 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 293 | LIBRARY_SEARCH_PATHS = ( 294 | "$(SRCROOT)", 295 | "$(inherited)", 296 | ); 297 | ONLY_ACTIVE_ARCH = NO; 298 | OTHER_LDFLAGS = "-ObjC"; 299 | PRODUCT_NAME = SubstrateSign; 300 | SKIP_INSTALL = YES; 301 | SWIFT_OBJC_BRIDGING_HEADER = "SubstrateSign-Bridging-Header.h"; 302 | SWIFT_VERSION = 5.0; 303 | }; 304 | name = Release; 305 | }; 306 | /* End XCBuildConfiguration section */ 307 | 308 | /* Begin XCConfigurationList section */ 309 | 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "SubstrateSign" */ = { 310 | isa = XCConfigurationList; 311 | buildConfigurations = ( 312 | 58B511ED1A9E6C8500147676 /* Debug */, 313 | 58B511EE1A9E6C8500147676 /* Release */, 314 | ); 315 | defaultConfigurationIsVisible = 0; 316 | defaultConfigurationName = Release; 317 | }; 318 | 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "SubstrateSign" */ = { 319 | isa = XCConfigurationList; 320 | buildConfigurations = ( 321 | 58B511F01A9E6C8500147676 /* Debug */, 322 | 58B511F11A9E6C8500147676 /* Release */, 323 | ); 324 | defaultConfigurationIsVisible = 0; 325 | defaultConfigurationName = Release; 326 | }; 327 | /* End XCConfigurationList section */ 328 | }; 329 | rootObject = 58B511D31A9E6C8500147676 /* Project object */; 330 | } 331 | -------------------------------------------------------------------------------- /ios/SubstrateSign.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/SubstrateSign.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/libsigner.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paritytech/react-native-substrate-sign/9b1043bf2ebf52b97a5c1f9e68ed41048263f82b/ios/libsigner.a -------------------------------------------------------------------------------- /ios/signer.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2020 Parity Technologies (UK) Ltd. 2 | // This file is part of Parity. 3 | 4 | // Parity is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | 9 | // Parity is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | 14 | // You should have received a copy of the GNU General Public License 15 | // along with Parity. If not, see . 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | // rust ffi 22 | 23 | struct ExternError { 24 | int32_t code; 25 | char *message; // note: nullable 26 | }; 27 | 28 | void signer_destroy_string(const char* cstring); 29 | 30 | // ethkey ffi 31 | 32 | // return keypair address, automatically picking BIP39 or parity phrases 33 | const char* ethkey_brainwallet_address(struct ExternError*, const char* seed); 34 | 35 | // return keypair address from BIP39 phrase 36 | const char* ethkey_brainwallet_bip39_address(struct ExternError*, const char* seed); 37 | 38 | // returns message signed with keypair 39 | const char* ethkey_brainwallet_sign(struct ExternError*, const char* seed, const char* message); 40 | 41 | // returns rlp item at given position 42 | const char* rlp_item(struct ExternError*, const char* rlp, const unsigned position); 43 | 44 | const char* keccak256(struct ExternError*, const char* data); 45 | 46 | const char* blake(struct ExternError*, const char* data); 47 | 48 | const char* eth_sign(struct ExternError*, const char* data); 49 | 50 | const char* blockies_icon(struct ExternError*, const char* blockies_seed); 51 | 52 | const char* random_phrase(struct ExternError*, int words_number); 53 | 54 | const char* encrypt_data(struct ExternError*, const char* data, const char* password); 55 | 56 | const char* decrypt_data(struct ExternError*, const char* encrypted_data, const char* password); 57 | 58 | // qr code generator for utf-8 strings 59 | const char* qrcode(struct ExternError*, const char* data); 60 | 61 | // qr code generator for hex-encoded binary 62 | const char* qrcode_hex(struct ExternError*, const char* data); 63 | 64 | // ss58 address (including prefix) for sr25519 key generated out of BIP39 phrase 65 | const char* substrate_brainwallet_address(struct ExternError*, const char* seed, const unsigned prefix); 66 | 67 | const char* substrate_brainwallet_sign(struct ExternError* err, const char* seed, const char* data); 68 | 69 | const char* schnorrkel_verify(struct ExternError*, const char* seed, const char* msg, const char* signature); 70 | 71 | int64_t decrypt_data_ref(struct ExternError*, const char* encrypted_data, const char* password); 72 | 73 | void destroy_data_ref(struct ExternError*, int64_t data_ref); 74 | 75 | const char* ethkey_brainwallet_sign_with_ref(struct ExternError*, int64_t seed_ref, const char* message); 76 | 77 | const char* substrate_brainwallet_sign_with_ref(struct ExternError*, int64_t seed_ref, const char* suri_suffix, const char* data); 78 | 79 | const char* substrate_address_with_ref(struct ExternError*, int64_t seed_ref, const char* suri_suffix, const unsigned prefix); 80 | 81 | const char* brain_wallet_address_with_ref(struct ExternError*, int64_t seed_ref); 82 | 83 | const char* substrate_mini_secret_key_with_ref(struct ExternError*, int64_t seed_ref, const char* suri_suffix); 84 | 85 | const char* substrate_mini_secret_key(struct ExternError*, const char* suri); 86 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-substrate-sign", 3 | "title": "React Native Substrate Sign", 4 | "version": "1.1.1", 5 | "description": "The react native crypto library written in Rust for Substrate, Polkadot and Ethereum", 6 | "main": "index.js", 7 | "scripts": { 8 | "test": "(cd ./rust/signer && cargo test)", 9 | "clean": "(cd rust/signer && cargo clean)", 10 | "build": "./scripts/build.sh" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/paritytech/react-native-substrate-sign.git", 15 | "baseUrl": "https://github.com/paritytech/react-native-substrate-sign" 16 | }, 17 | "keywords": [ 18 | "react-native", 19 | "crypto", 20 | "substrate", 21 | "polkadot", 22 | "ethereum" 23 | ], 24 | "author": { 25 | "name": "Admin", 26 | "email": "admin@parity.io" 27 | }, 28 | "license": "Apache-2", 29 | "licenseFilename": "LICENSE", 30 | "readmeFilename": "README.md", 31 | "peerDependencies": { 32 | "react": "^16.8.1", 33 | "react-native": ">=0.60.0-rc.0 <1.0.x" 34 | }, 35 | "devDependencies": { 36 | "react": "^16.9.0", 37 | "react-native": "^0.61.5" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /react-native-substrate-sign.podspec: -------------------------------------------------------------------------------- 1 | require "json" 2 | 3 | package = JSON.parse(File.read(File.join(__dir__, "package.json"))) 4 | 5 | Pod::Spec.new do |s| 6 | s.name = "react-native-substrate-sign" 7 | s.version = package["version"] 8 | s.summary = package["description"] 9 | s.description = <<-DESC 10 | react-native-substrate-sign 11 | DESC 12 | s.homepage = "https://github.com/paritytech/react-native-substrate-sign" 13 | s.license = "Apache-2" 14 | s.authors = { "Admin" => "admin@parity.io" } 15 | s.platforms = { :ios => "9.0" } 16 | s.source = { :git => "https://github.com/paritytech/react-native-substrate-sign.git", :tag => "#{s.version}" } 17 | s.vendored_libraries = 'ios/libsigner.a' 18 | s.source_files = "ios/**/*.{h,c,m,swift}" 19 | s.requires_arc = true 20 | 21 | s.dependency "React" 22 | # ... 23 | # s.dependency "..." 24 | end 25 | 26 | -------------------------------------------------------------------------------- /rust/signer/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | -------------------------------------------------------------------------------- /rust/signer/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "adler32" 5 | version = "1.0.4" 6 | source = "registry+https://github.com/rust-lang/crates.io-index" 7 | 8 | [[package]] 9 | name = "aes-ctr" 10 | version = "0.3.0" 11 | source = "registry+https://github.com/rust-lang/crates.io-index" 12 | dependencies = [ 13 | "aes-soft 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 14 | "aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", 15 | "ctr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 16 | "stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 17 | ] 18 | 19 | [[package]] 20 | name = "aes-soft" 21 | version = "0.3.3" 22 | source = "registry+https://github.com/rust-lang/crates.io-index" 23 | dependencies = [ 24 | "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", 25 | "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 26 | "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 27 | ] 28 | 29 | [[package]] 30 | name = "aesni" 31 | version = "0.6.0" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | dependencies = [ 34 | "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", 35 | "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 36 | "stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 37 | ] 38 | 39 | [[package]] 40 | name = "aho-corasick" 41 | version = "0.7.6" 42 | source = "registry+https://github.com/rust-lang/crates.io-index" 43 | dependencies = [ 44 | "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 45 | ] 46 | 47 | [[package]] 48 | name = "anyhow" 49 | version = "1.0.28" 50 | source = "registry+https://github.com/rust-lang/crates.io-index" 51 | 52 | [[package]] 53 | name = "arrayref" 54 | version = "0.3.5" 55 | source = "registry+https://github.com/rust-lang/crates.io-index" 56 | 57 | [[package]] 58 | name = "arrayvec" 59 | version = "0.4.12" 60 | source = "registry+https://github.com/rust-lang/crates.io-index" 61 | dependencies = [ 62 | "nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", 63 | ] 64 | 65 | [[package]] 66 | name = "ascii" 67 | version = "0.9.3" 68 | source = "registry+https://github.com/rust-lang/crates.io-index" 69 | 70 | [[package]] 71 | name = "autocfg" 72 | version = "0.1.6" 73 | source = "registry+https://github.com/rust-lang/crates.io-index" 74 | 75 | [[package]] 76 | name = "backtrace" 77 | version = "0.3.38" 78 | source = "registry+https://github.com/rust-lang/crates.io-index" 79 | dependencies = [ 80 | "backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", 81 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 82 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 83 | "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 84 | ] 85 | 86 | [[package]] 87 | name = "backtrace-sys" 88 | version = "0.1.31" 89 | source = "registry+https://github.com/rust-lang/crates.io-index" 90 | dependencies = [ 91 | "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", 92 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 93 | ] 94 | 95 | [[package]] 96 | name = "base58" 97 | version = "0.1.0" 98 | source = "registry+https://github.com/rust-lang/crates.io-index" 99 | 100 | [[package]] 101 | name = "base64" 102 | version = "0.9.3" 103 | source = "registry+https://github.com/rust-lang/crates.io-index" 104 | dependencies = [ 105 | "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 106 | "safemem 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 107 | ] 108 | 109 | [[package]] 110 | name = "base64" 111 | version = "0.10.1" 112 | source = "registry+https://github.com/rust-lang/crates.io-index" 113 | dependencies = [ 114 | "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 115 | ] 116 | 117 | [[package]] 118 | name = "bitflags" 119 | version = "1.2.1" 120 | source = "registry+https://github.com/rust-lang/crates.io-index" 121 | 122 | [[package]] 123 | name = "blake2-rfc" 124 | version = "0.2.18" 125 | source = "registry+https://github.com/rust-lang/crates.io-index" 126 | dependencies = [ 127 | "arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", 128 | "constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 129 | ] 130 | 131 | [[package]] 132 | name = "block-buffer" 133 | version = "0.2.0" 134 | source = "registry+https://github.com/rust-lang/crates.io-index" 135 | dependencies = [ 136 | "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 137 | "generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", 138 | ] 139 | 140 | [[package]] 141 | name = "block-buffer" 142 | version = "0.7.3" 143 | source = "registry+https://github.com/rust-lang/crates.io-index" 144 | dependencies = [ 145 | "block-padding 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 146 | "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 147 | "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 148 | "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", 149 | ] 150 | 151 | [[package]] 152 | name = "block-cipher-trait" 153 | version = "0.6.2" 154 | source = "registry+https://github.com/rust-lang/crates.io-index" 155 | dependencies = [ 156 | "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", 157 | ] 158 | 159 | [[package]] 160 | name = "block-padding" 161 | version = "0.1.4" 162 | source = "registry+https://github.com/rust-lang/crates.io-index" 163 | dependencies = [ 164 | "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 165 | ] 166 | 167 | [[package]] 168 | name = "blockies" 169 | version = "0.3.0" 170 | source = "registry+https://github.com/rust-lang/crates.io-index" 171 | dependencies = [ 172 | "hsl 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 173 | "pixelate 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 174 | ] 175 | 176 | [[package]] 177 | name = "byte-tools" 178 | version = "0.2.0" 179 | source = "registry+https://github.com/rust-lang/crates.io-index" 180 | 181 | [[package]] 182 | name = "byte-tools" 183 | version = "0.3.1" 184 | source = "registry+https://github.com/rust-lang/crates.io-index" 185 | 186 | [[package]] 187 | name = "byteorder" 188 | version = "1.3.2" 189 | source = "registry+https://github.com/rust-lang/crates.io-index" 190 | 191 | [[package]] 192 | name = "c2-chacha" 193 | version = "0.2.2" 194 | source = "registry+https://github.com/rust-lang/crates.io-index" 195 | dependencies = [ 196 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 197 | "ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", 198 | ] 199 | 200 | [[package]] 201 | name = "cc" 202 | version = "1.0.45" 203 | source = "registry+https://github.com/rust-lang/crates.io-index" 204 | 205 | [[package]] 206 | name = "cesu8" 207 | version = "1.1.0" 208 | source = "registry+https://github.com/rust-lang/crates.io-index" 209 | 210 | [[package]] 211 | name = "cfg-if" 212 | version = "0.1.10" 213 | source = "registry+https://github.com/rust-lang/crates.io-index" 214 | 215 | [[package]] 216 | name = "clear_on_drop" 217 | version = "0.2.3" 218 | source = "registry+https://github.com/rust-lang/crates.io-index" 219 | dependencies = [ 220 | "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", 221 | ] 222 | 223 | [[package]] 224 | name = "cloudabi" 225 | version = "0.0.3" 226 | source = "registry+https://github.com/rust-lang/crates.io-index" 227 | dependencies = [ 228 | "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 229 | ] 230 | 231 | [[package]] 232 | name = "combine" 233 | version = "3.8.1" 234 | source = "registry+https://github.com/rust-lang/crates.io-index" 235 | dependencies = [ 236 | "ascii 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", 237 | "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 238 | "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", 239 | "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 240 | "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 241 | ] 242 | 243 | [[package]] 244 | name = "constant_time_eq" 245 | version = "0.1.4" 246 | source = "registry+https://github.com/rust-lang/crates.io-index" 247 | 248 | [[package]] 249 | name = "crossbeam-deque" 250 | version = "0.7.1" 251 | source = "registry+https://github.com/rust-lang/crates.io-index" 252 | dependencies = [ 253 | "crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 254 | "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", 255 | ] 256 | 257 | [[package]] 258 | name = "crossbeam-epoch" 259 | version = "0.7.2" 260 | source = "registry+https://github.com/rust-lang/crates.io-index" 261 | dependencies = [ 262 | "arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", 263 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 264 | "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", 265 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 266 | "memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 267 | "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 268 | ] 269 | 270 | [[package]] 271 | name = "crossbeam-queue" 272 | version = "0.1.2" 273 | source = "registry+https://github.com/rust-lang/crates.io-index" 274 | dependencies = [ 275 | "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", 276 | ] 277 | 278 | [[package]] 279 | name = "crossbeam-utils" 280 | version = "0.6.6" 281 | source = "registry+https://github.com/rust-lang/crates.io-index" 282 | dependencies = [ 283 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 284 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 285 | ] 286 | 287 | [[package]] 288 | name = "crunchy" 289 | version = "0.1.6" 290 | source = "registry+https://github.com/rust-lang/crates.io-index" 291 | 292 | [[package]] 293 | name = "crunchy" 294 | version = "0.2.2" 295 | source = "registry+https://github.com/rust-lang/crates.io-index" 296 | 297 | [[package]] 298 | name = "crypto-mac" 299 | version = "0.4.0" 300 | source = "registry+https://github.com/rust-lang/crates.io-index" 301 | dependencies = [ 302 | "constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 303 | "generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", 304 | ] 305 | 306 | [[package]] 307 | name = "crypto-mac" 308 | version = "0.7.0" 309 | source = "registry+https://github.com/rust-lang/crates.io-index" 310 | dependencies = [ 311 | "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", 312 | "subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 313 | ] 314 | 315 | [[package]] 316 | name = "ctr" 317 | version = "0.3.2" 318 | source = "registry+https://github.com/rust-lang/crates.io-index" 319 | dependencies = [ 320 | "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", 321 | "stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 322 | ] 323 | 324 | [[package]] 325 | name = "curve25519-dalek" 326 | version = "1.2.3" 327 | source = "registry+https://github.com/rust-lang/crates.io-index" 328 | dependencies = [ 329 | "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 330 | "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 331 | "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", 332 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 333 | "subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 334 | ] 335 | 336 | [[package]] 337 | name = "deflate" 338 | version = "0.7.20" 339 | source = "registry+https://github.com/rust-lang/crates.io-index" 340 | dependencies = [ 341 | "adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 342 | "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 343 | ] 344 | 345 | [[package]] 346 | name = "digest" 347 | version = "0.6.2" 348 | source = "registry+https://github.com/rust-lang/crates.io-index" 349 | dependencies = [ 350 | "generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", 351 | ] 352 | 353 | [[package]] 354 | name = "digest" 355 | version = "0.8.1" 356 | source = "registry+https://github.com/rust-lang/crates.io-index" 357 | dependencies = [ 358 | "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", 359 | ] 360 | 361 | [[package]] 362 | name = "either" 363 | version = "1.5.3" 364 | source = "registry+https://github.com/rust-lang/crates.io-index" 365 | 366 | [[package]] 367 | name = "error-chain" 368 | version = "0.12.1" 369 | source = "registry+https://github.com/rust-lang/crates.io-index" 370 | dependencies = [ 371 | "backtrace 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)", 372 | "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 373 | ] 374 | 375 | [[package]] 376 | name = "ethbloom" 377 | version = "0.5.3" 378 | source = "registry+https://github.com/rust-lang/crates.io-index" 379 | dependencies = [ 380 | "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 381 | "ethereum-types-serialize 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 382 | "fixed-hash 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", 383 | "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", 384 | "tiny-keccak 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", 385 | ] 386 | 387 | [[package]] 388 | name = "ethereum-types" 389 | version = "0.4.2" 390 | source = "registry+https://github.com/rust-lang/crates.io-index" 391 | dependencies = [ 392 | "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 393 | "ethbloom 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", 394 | "ethereum-types-serialize 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 395 | "fixed-hash 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", 396 | "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", 397 | "uint 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", 398 | ] 399 | 400 | [[package]] 401 | name = "ethereum-types-serialize" 402 | version = "0.2.2" 403 | source = "registry+https://github.com/rust-lang/crates.io-index" 404 | dependencies = [ 405 | "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", 406 | ] 407 | 408 | [[package]] 409 | name = "ethsign" 410 | version = "0.7.3" 411 | source = "registry+https://github.com/rust-lang/crates.io-index" 412 | dependencies = [ 413 | "ethsign-crypto 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 414 | "libsecp256k1 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 415 | "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 416 | "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 417 | "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", 418 | "zeroize 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 419 | ] 420 | 421 | [[package]] 422 | name = "ethsign-crypto" 423 | version = "0.2.1" 424 | source = "registry+https://github.com/rust-lang/crates.io-index" 425 | dependencies = [ 426 | "aes-ctr 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 427 | "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", 428 | "pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 429 | "scrypt 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 430 | "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", 431 | "tiny-keccak 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", 432 | ] 433 | 434 | [[package]] 435 | name = "failure" 436 | version = "0.1.6" 437 | source = "registry+https://github.com/rust-lang/crates.io-index" 438 | dependencies = [ 439 | "backtrace 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)", 440 | "failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 441 | ] 442 | 443 | [[package]] 444 | name = "failure_derive" 445 | version = "0.1.6" 446 | source = "registry+https://github.com/rust-lang/crates.io-index" 447 | dependencies = [ 448 | "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", 449 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 450 | "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", 451 | "synstructure 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", 452 | ] 453 | 454 | [[package]] 455 | name = "fake-simd" 456 | version = "0.1.2" 457 | source = "registry+https://github.com/rust-lang/crates.io-index" 458 | 459 | [[package]] 460 | name = "ffi-support" 461 | version = "0.4.0" 462 | source = "registry+https://github.com/rust-lang/crates.io-index" 463 | dependencies = [ 464 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 465 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 466 | ] 467 | 468 | [[package]] 469 | name = "fixed-hash" 470 | version = "0.2.5" 471 | source = "registry+https://github.com/rust-lang/crates.io-index" 472 | dependencies = [ 473 | "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 474 | "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 475 | "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 476 | ] 477 | 478 | [[package]] 479 | name = "fuchsia-cprng" 480 | version = "0.1.1" 481 | source = "registry+https://github.com/rust-lang/crates.io-index" 482 | 483 | [[package]] 484 | name = "generic-array" 485 | version = "0.8.3" 486 | source = "registry+https://github.com/rust-lang/crates.io-index" 487 | dependencies = [ 488 | "nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", 489 | "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", 490 | ] 491 | 492 | [[package]] 493 | name = "generic-array" 494 | version = "0.12.3" 495 | source = "registry+https://github.com/rust-lang/crates.io-index" 496 | dependencies = [ 497 | "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", 498 | ] 499 | 500 | [[package]] 501 | name = "getrandom" 502 | version = "0.1.12" 503 | source = "registry+https://github.com/rust-lang/crates.io-index" 504 | dependencies = [ 505 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 506 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 507 | "wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 508 | ] 509 | 510 | [[package]] 511 | name = "hashbrown" 512 | version = "0.1.8" 513 | source = "registry+https://github.com/rust-lang/crates.io-index" 514 | dependencies = [ 515 | "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 516 | "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 517 | ] 518 | 519 | [[package]] 520 | name = "heapsize" 521 | version = "0.4.2" 522 | source = "registry+https://github.com/rust-lang/crates.io-index" 523 | dependencies = [ 524 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 525 | ] 526 | 527 | [[package]] 528 | name = "hmac" 529 | version = "0.4.2" 530 | source = "registry+https://github.com/rust-lang/crates.io-index" 531 | dependencies = [ 532 | "crypto-mac 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 533 | "digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", 534 | "generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", 535 | ] 536 | 537 | [[package]] 538 | name = "hmac" 539 | version = "0.7.1" 540 | source = "registry+https://github.com/rust-lang/crates.io-index" 541 | dependencies = [ 542 | "crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 543 | "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", 544 | ] 545 | 546 | [[package]] 547 | name = "hmac-drbg" 548 | version = "0.1.2" 549 | source = "registry+https://github.com/rust-lang/crates.io-index" 550 | dependencies = [ 551 | "digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", 552 | "generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", 553 | "hmac 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 554 | ] 555 | 556 | [[package]] 557 | name = "hmac-drbg" 558 | version = "0.2.0" 559 | source = "registry+https://github.com/rust-lang/crates.io-index" 560 | dependencies = [ 561 | "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", 562 | "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", 563 | "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", 564 | ] 565 | 566 | [[package]] 567 | name = "hsl" 568 | version = "0.1.1" 569 | source = "registry+https://github.com/rust-lang/crates.io-index" 570 | 571 | [[package]] 572 | name = "inflate" 573 | version = "0.4.5" 574 | source = "registry+https://github.com/rust-lang/crates.io-index" 575 | dependencies = [ 576 | "adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 577 | ] 578 | 579 | [[package]] 580 | name = "itoa" 581 | version = "0.4.4" 582 | source = "registry+https://github.com/rust-lang/crates.io-index" 583 | 584 | [[package]] 585 | name = "jni" 586 | version = "0.16.0" 587 | source = "registry+https://github.com/rust-lang/crates.io-index" 588 | dependencies = [ 589 | "cesu8 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 590 | "combine 3.8.1 (registry+https://github.com/rust-lang/crates.io-index)", 591 | "error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", 592 | "jni-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 593 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 594 | "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", 595 | ] 596 | 597 | [[package]] 598 | name = "jni-sys" 599 | version = "0.3.0" 600 | source = "registry+https://github.com/rust-lang/crates.io-index" 601 | 602 | [[package]] 603 | name = "keccak" 604 | version = "0.1.0" 605 | source = "registry+https://github.com/rust-lang/crates.io-index" 606 | 607 | [[package]] 608 | name = "lazy_static" 609 | version = "1.4.0" 610 | source = "registry+https://github.com/rust-lang/crates.io-index" 611 | 612 | [[package]] 613 | name = "libc" 614 | version = "0.2.62" 615 | source = "registry+https://github.com/rust-lang/crates.io-index" 616 | 617 | [[package]] 618 | name = "libsecp256k1" 619 | version = "0.2.2" 620 | source = "registry+https://github.com/rust-lang/crates.io-index" 621 | dependencies = [ 622 | "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 623 | "digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", 624 | "hmac-drbg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 625 | "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 626 | "sha2 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", 627 | "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", 628 | ] 629 | 630 | [[package]] 631 | name = "libsecp256k1" 632 | version = "0.3.1" 633 | source = "registry+https://github.com/rust-lang/crates.io-index" 634 | dependencies = [ 635 | "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 636 | "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", 637 | "hmac-drbg 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 638 | "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", 639 | "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", 640 | "subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 641 | "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", 642 | ] 643 | 644 | [[package]] 645 | name = "lock_api" 646 | version = "0.1.5" 647 | source = "registry+https://github.com/rust-lang/crates.io-index" 648 | dependencies = [ 649 | "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 650 | ] 651 | 652 | [[package]] 653 | name = "log" 654 | version = "0.4.8" 655 | source = "registry+https://github.com/rust-lang/crates.io-index" 656 | dependencies = [ 657 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 658 | ] 659 | 660 | [[package]] 661 | name = "memchr" 662 | version = "2.2.1" 663 | source = "registry+https://github.com/rust-lang/crates.io-index" 664 | 665 | [[package]] 666 | name = "memoffset" 667 | version = "0.5.1" 668 | source = "registry+https://github.com/rust-lang/crates.io-index" 669 | dependencies = [ 670 | "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 671 | ] 672 | 673 | [[package]] 674 | name = "merlin" 675 | version = "1.2.1" 676 | source = "registry+https://github.com/rust-lang/crates.io-index" 677 | dependencies = [ 678 | "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 679 | "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 680 | "keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 681 | "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 682 | ] 683 | 684 | [[package]] 685 | name = "nodrop" 686 | version = "0.1.14" 687 | source = "registry+https://github.com/rust-lang/crates.io-index" 688 | 689 | [[package]] 690 | name = "num-integer" 691 | version = "0.1.41" 692 | source = "registry+https://github.com/rust-lang/crates.io-index" 693 | dependencies = [ 694 | "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 695 | "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 696 | ] 697 | 698 | [[package]] 699 | name = "num-iter" 700 | version = "0.1.39" 701 | source = "registry+https://github.com/rust-lang/crates.io-index" 702 | dependencies = [ 703 | "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 704 | "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", 705 | "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 706 | ] 707 | 708 | [[package]] 709 | name = "num-traits" 710 | version = "0.2.8" 711 | source = "registry+https://github.com/rust-lang/crates.io-index" 712 | dependencies = [ 713 | "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 714 | ] 715 | 716 | [[package]] 717 | name = "num_cpus" 718 | version = "1.10.1" 719 | source = "registry+https://github.com/rust-lang/crates.io-index" 720 | dependencies = [ 721 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 722 | ] 723 | 724 | [[package]] 725 | name = "once_cell" 726 | version = "0.1.8" 727 | source = "registry+https://github.com/rust-lang/crates.io-index" 728 | dependencies = [ 729 | "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", 730 | ] 731 | 732 | [[package]] 733 | name = "opaque-debug" 734 | version = "0.2.3" 735 | source = "registry+https://github.com/rust-lang/crates.io-index" 736 | 737 | [[package]] 738 | name = "parity-scale-codec" 739 | version = "1.0.6" 740 | source = "registry+https://github.com/rust-lang/crates.io-index" 741 | dependencies = [ 742 | "arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", 743 | "parity-scale-codec-derive 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 744 | ] 745 | 746 | [[package]] 747 | name = "parity-scale-codec-derive" 748 | version = "1.0.3" 749 | source = "registry+https://github.com/rust-lang/crates.io-index" 750 | dependencies = [ 751 | "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 752 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 753 | "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", 754 | "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", 755 | ] 756 | 757 | [[package]] 758 | name = "parking_lot" 759 | version = "0.7.1" 760 | source = "registry+https://github.com/rust-lang/crates.io-index" 761 | dependencies = [ 762 | "lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 763 | "parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 764 | ] 765 | 766 | [[package]] 767 | name = "parking_lot_core" 768 | version = "0.4.0" 769 | source = "registry+https://github.com/rust-lang/crates.io-index" 770 | dependencies = [ 771 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 772 | "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", 773 | "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 774 | "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", 775 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 776 | ] 777 | 778 | [[package]] 779 | name = "pbkdf2" 780 | version = "0.3.0" 781 | source = "registry+https://github.com/rust-lang/crates.io-index" 782 | dependencies = [ 783 | "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 784 | "crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 785 | "rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 786 | ] 787 | 788 | [[package]] 789 | name = "pixelate" 790 | version = "0.1.0" 791 | source = "registry+https://github.com/rust-lang/crates.io-index" 792 | dependencies = [ 793 | "png 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", 794 | ] 795 | 796 | [[package]] 797 | name = "png" 798 | version = "0.14.1" 799 | source = "registry+https://github.com/rust-lang/crates.io-index" 800 | dependencies = [ 801 | "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 802 | "deflate 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)", 803 | "inflate 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", 804 | "num-iter 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", 805 | ] 806 | 807 | [[package]] 808 | name = "ppv-lite86" 809 | version = "0.2.5" 810 | source = "registry+https://github.com/rust-lang/crates.io-index" 811 | 812 | [[package]] 813 | name = "proc-macro-crate" 814 | version = "0.1.4" 815 | source = "registry+https://github.com/rust-lang/crates.io-index" 816 | dependencies = [ 817 | "toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", 818 | ] 819 | 820 | [[package]] 821 | name = "proc-macro2" 822 | version = "0.4.30" 823 | source = "registry+https://github.com/rust-lang/crates.io-index" 824 | dependencies = [ 825 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 826 | ] 827 | 828 | [[package]] 829 | name = "proc-macro2" 830 | version = "1.0.5" 831 | source = "registry+https://github.com/rust-lang/crates.io-index" 832 | dependencies = [ 833 | "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 834 | ] 835 | 836 | [[package]] 837 | name = "qrcodegen" 838 | version = "1.5.0" 839 | source = "registry+https://github.com/rust-lang/crates.io-index" 840 | 841 | [[package]] 842 | name = "quote" 843 | version = "0.6.13" 844 | source = "registry+https://github.com/rust-lang/crates.io-index" 845 | dependencies = [ 846 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 847 | ] 848 | 849 | [[package]] 850 | name = "quote" 851 | version = "1.0.2" 852 | source = "registry+https://github.com/rust-lang/crates.io-index" 853 | dependencies = [ 854 | "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", 855 | ] 856 | 857 | [[package]] 858 | name = "rand" 859 | version = "0.4.6" 860 | source = "registry+https://github.com/rust-lang/crates.io-index" 861 | dependencies = [ 862 | "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 863 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 864 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 865 | "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 866 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 867 | ] 868 | 869 | [[package]] 870 | name = "rand" 871 | version = "0.5.6" 872 | source = "registry+https://github.com/rust-lang/crates.io-index" 873 | dependencies = [ 874 | "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 875 | "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 876 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 877 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 878 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 879 | ] 880 | 881 | [[package]] 882 | name = "rand" 883 | version = "0.6.5" 884 | source = "registry+https://github.com/rust-lang/crates.io-index" 885 | dependencies = [ 886 | "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 887 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 888 | "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 889 | "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 890 | "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 891 | "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 892 | "rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 893 | "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 894 | "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 895 | "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 896 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 897 | ] 898 | 899 | [[package]] 900 | name = "rand" 901 | version = "0.7.2" 902 | source = "registry+https://github.com/rust-lang/crates.io-index" 903 | dependencies = [ 904 | "getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 905 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 906 | "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 907 | "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 908 | "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 909 | ] 910 | 911 | [[package]] 912 | name = "rand_chacha" 913 | version = "0.1.1" 914 | source = "registry+https://github.com/rust-lang/crates.io-index" 915 | dependencies = [ 916 | "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 917 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 918 | ] 919 | 920 | [[package]] 921 | name = "rand_chacha" 922 | version = "0.2.1" 923 | source = "registry+https://github.com/rust-lang/crates.io-index" 924 | dependencies = [ 925 | "c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 926 | "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 927 | ] 928 | 929 | [[package]] 930 | name = "rand_core" 931 | version = "0.3.1" 932 | source = "registry+https://github.com/rust-lang/crates.io-index" 933 | dependencies = [ 934 | "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 935 | ] 936 | 937 | [[package]] 938 | name = "rand_core" 939 | version = "0.4.2" 940 | source = "registry+https://github.com/rust-lang/crates.io-index" 941 | 942 | [[package]] 943 | name = "rand_core" 944 | version = "0.5.1" 945 | source = "registry+https://github.com/rust-lang/crates.io-index" 946 | dependencies = [ 947 | "getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 948 | ] 949 | 950 | [[package]] 951 | name = "rand_hc" 952 | version = "0.1.0" 953 | source = "registry+https://github.com/rust-lang/crates.io-index" 954 | dependencies = [ 955 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 956 | ] 957 | 958 | [[package]] 959 | name = "rand_hc" 960 | version = "0.2.0" 961 | source = "registry+https://github.com/rust-lang/crates.io-index" 962 | dependencies = [ 963 | "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 964 | ] 965 | 966 | [[package]] 967 | name = "rand_isaac" 968 | version = "0.1.1" 969 | source = "registry+https://github.com/rust-lang/crates.io-index" 970 | dependencies = [ 971 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 972 | ] 973 | 974 | [[package]] 975 | name = "rand_jitter" 976 | version = "0.1.4" 977 | source = "registry+https://github.com/rust-lang/crates.io-index" 978 | dependencies = [ 979 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 980 | "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 981 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 982 | ] 983 | 984 | [[package]] 985 | name = "rand_os" 986 | version = "0.1.3" 987 | source = "registry+https://github.com/rust-lang/crates.io-index" 988 | dependencies = [ 989 | "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 990 | "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 991 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 992 | "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 993 | "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 994 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 995 | ] 996 | 997 | [[package]] 998 | name = "rand_pcg" 999 | version = "0.1.2" 1000 | source = "registry+https://github.com/rust-lang/crates.io-index" 1001 | dependencies = [ 1002 | "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 1003 | "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 1004 | ] 1005 | 1006 | [[package]] 1007 | name = "rand_xorshift" 1008 | version = "0.1.1" 1009 | source = "registry+https://github.com/rust-lang/crates.io-index" 1010 | dependencies = [ 1011 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 1012 | ] 1013 | 1014 | [[package]] 1015 | name = "rayon" 1016 | version = "1.2.0" 1017 | source = "registry+https://github.com/rust-lang/crates.io-index" 1018 | dependencies = [ 1019 | "crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", 1020 | "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", 1021 | "rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", 1022 | ] 1023 | 1024 | [[package]] 1025 | name = "rayon-core" 1026 | version = "1.6.0" 1027 | source = "registry+https://github.com/rust-lang/crates.io-index" 1028 | dependencies = [ 1029 | "crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", 1030 | "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 1031 | "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", 1032 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1033 | "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", 1034 | ] 1035 | 1036 | [[package]] 1037 | name = "rdrand" 1038 | version = "0.4.0" 1039 | source = "registry+https://github.com/rust-lang/crates.io-index" 1040 | dependencies = [ 1041 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 1042 | ] 1043 | 1044 | [[package]] 1045 | name = "regex" 1046 | version = "1.3.1" 1047 | source = "registry+https://github.com/rust-lang/crates.io-index" 1048 | dependencies = [ 1049 | "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", 1050 | "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 1051 | "regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", 1052 | "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 1053 | ] 1054 | 1055 | [[package]] 1056 | name = "regex-syntax" 1057 | version = "0.6.12" 1058 | source = "registry+https://github.com/rust-lang/crates.io-index" 1059 | 1060 | [[package]] 1061 | name = "rlp" 1062 | version = "0.3.0" 1063 | source = "registry+https://github.com/rust-lang/crates.io-index" 1064 | dependencies = [ 1065 | "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 1066 | "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 1067 | "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1068 | ] 1069 | 1070 | [[package]] 1071 | name = "rustc-demangle" 1072 | version = "0.1.16" 1073 | source = "registry+https://github.com/rust-lang/crates.io-index" 1074 | 1075 | [[package]] 1076 | name = "rustc-hex" 1077 | version = "2.0.1" 1078 | source = "registry+https://github.com/rust-lang/crates.io-index" 1079 | 1080 | [[package]] 1081 | name = "rustc_version" 1082 | version = "0.2.3" 1083 | source = "registry+https://github.com/rust-lang/crates.io-index" 1084 | dependencies = [ 1085 | "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 1086 | ] 1087 | 1088 | [[package]] 1089 | name = "ryu" 1090 | version = "1.0.2" 1091 | source = "registry+https://github.com/rust-lang/crates.io-index" 1092 | 1093 | [[package]] 1094 | name = "safemem" 1095 | version = "0.3.2" 1096 | source = "registry+https://github.com/rust-lang/crates.io-index" 1097 | 1098 | [[package]] 1099 | name = "same-file" 1100 | version = "1.0.5" 1101 | source = "registry+https://github.com/rust-lang/crates.io-index" 1102 | dependencies = [ 1103 | "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 1104 | ] 1105 | 1106 | [[package]] 1107 | name = "schnorrkel" 1108 | version = "0.8.5" 1109 | source = "registry+https://github.com/rust-lang/crates.io-index" 1110 | dependencies = [ 1111 | "curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 1112 | "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 1113 | "merlin 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 1114 | "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", 1115 | "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 1116 | "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 1117 | "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", 1118 | "subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 1119 | "zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", 1120 | ] 1121 | 1122 | [[package]] 1123 | name = "scopeguard" 1124 | version = "0.3.3" 1125 | source = "registry+https://github.com/rust-lang/crates.io-index" 1126 | 1127 | [[package]] 1128 | name = "scopeguard" 1129 | version = "1.0.0" 1130 | source = "registry+https://github.com/rust-lang/crates.io-index" 1131 | 1132 | [[package]] 1133 | name = "scrypt" 1134 | version = "0.2.0" 1135 | source = "registry+https://github.com/rust-lang/crates.io-index" 1136 | dependencies = [ 1137 | "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", 1138 | "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 1139 | "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 1140 | "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", 1141 | "pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 1142 | "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", 1143 | "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", 1144 | "subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 1145 | ] 1146 | 1147 | [[package]] 1148 | name = "semver" 1149 | version = "0.9.0" 1150 | source = "registry+https://github.com/rust-lang/crates.io-index" 1151 | dependencies = [ 1152 | "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 1153 | ] 1154 | 1155 | [[package]] 1156 | name = "semver-parser" 1157 | version = "0.7.0" 1158 | source = "registry+https://github.com/rust-lang/crates.io-index" 1159 | 1160 | [[package]] 1161 | name = "serde" 1162 | version = "1.0.101" 1163 | source = "registry+https://github.com/rust-lang/crates.io-index" 1164 | dependencies = [ 1165 | "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", 1166 | ] 1167 | 1168 | [[package]] 1169 | name = "serde_derive" 1170 | version = "1.0.101" 1171 | source = "registry+https://github.com/rust-lang/crates.io-index" 1172 | dependencies = [ 1173 | "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", 1174 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1175 | "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", 1176 | ] 1177 | 1178 | [[package]] 1179 | name = "serde_json" 1180 | version = "1.0.41" 1181 | source = "registry+https://github.com/rust-lang/crates.io-index" 1182 | dependencies = [ 1183 | "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", 1184 | "ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1185 | "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", 1186 | ] 1187 | 1188 | [[package]] 1189 | name = "sha2" 1190 | version = "0.6.0" 1191 | source = "registry+https://github.com/rust-lang/crates.io-index" 1192 | dependencies = [ 1193 | "block-buffer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 1194 | "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 1195 | "digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", 1196 | "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 1197 | "generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", 1198 | ] 1199 | 1200 | [[package]] 1201 | name = "sha2" 1202 | version = "0.8.0" 1203 | source = "registry+https://github.com/rust-lang/crates.io-index" 1204 | dependencies = [ 1205 | "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", 1206 | "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", 1207 | "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 1208 | "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 1209 | ] 1210 | 1211 | [[package]] 1212 | name = "signer" 1213 | version = "0.1.0" 1214 | dependencies = [ 1215 | "anyhow 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", 1216 | "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1217 | "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", 1218 | "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", 1219 | "blockies 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 1220 | "ethsign 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", 1221 | "ffi-support 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1222 | "jni 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", 1223 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1224 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 1225 | "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 1226 | "pixelate 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1227 | "qrcodegen 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", 1228 | "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 1229 | "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 1230 | "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1231 | "schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", 1232 | "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", 1233 | "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", 1234 | "substrate-bip39 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 1235 | "thiserror 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", 1236 | "tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", 1237 | "tiny-hderive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1238 | "tiny-keccak 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", 1239 | ] 1240 | 1241 | [[package]] 1242 | name = "smallvec" 1243 | version = "0.6.10" 1244 | source = "registry+https://github.com/rust-lang/crates.io-index" 1245 | 1246 | [[package]] 1247 | name = "stream-cipher" 1248 | version = "0.3.2" 1249 | source = "registry+https://github.com/rust-lang/crates.io-index" 1250 | dependencies = [ 1251 | "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", 1252 | ] 1253 | 1254 | [[package]] 1255 | name = "substrate-bip39" 1256 | version = "0.3.1" 1257 | source = "registry+https://github.com/rust-lang/crates.io-index" 1258 | dependencies = [ 1259 | "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", 1260 | "pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 1261 | "schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", 1262 | "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", 1263 | ] 1264 | 1265 | [[package]] 1266 | name = "subtle" 1267 | version = "1.0.0" 1268 | source = "registry+https://github.com/rust-lang/crates.io-index" 1269 | 1270 | [[package]] 1271 | name = "subtle" 1272 | version = "2.2.1" 1273 | source = "registry+https://github.com/rust-lang/crates.io-index" 1274 | 1275 | [[package]] 1276 | name = "syn" 1277 | version = "0.15.44" 1278 | source = "registry+https://github.com/rust-lang/crates.io-index" 1279 | dependencies = [ 1280 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 1281 | "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", 1282 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1283 | ] 1284 | 1285 | [[package]] 1286 | name = "syn" 1287 | version = "1.0.11" 1288 | source = "registry+https://github.com/rust-lang/crates.io-index" 1289 | dependencies = [ 1290 | "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", 1291 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1292 | "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 1293 | ] 1294 | 1295 | [[package]] 1296 | name = "synstructure" 1297 | version = "0.12.1" 1298 | source = "registry+https://github.com/rust-lang/crates.io-index" 1299 | dependencies = [ 1300 | "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", 1301 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1302 | "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", 1303 | "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 1304 | ] 1305 | 1306 | [[package]] 1307 | name = "thiserror" 1308 | version = "1.0.14" 1309 | source = "registry+https://github.com/rust-lang/crates.io-index" 1310 | dependencies = [ 1311 | "thiserror-impl 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", 1312 | ] 1313 | 1314 | [[package]] 1315 | name = "thiserror-impl" 1316 | version = "1.0.14" 1317 | source = "registry+https://github.com/rust-lang/crates.io-index" 1318 | dependencies = [ 1319 | "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", 1320 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1321 | "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", 1322 | ] 1323 | 1324 | [[package]] 1325 | name = "thread_local" 1326 | version = "0.3.6" 1327 | source = "registry+https://github.com/rust-lang/crates.io-index" 1328 | dependencies = [ 1329 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1330 | ] 1331 | 1332 | [[package]] 1333 | name = "tiny-bip39" 1334 | version = "0.6.2" 1335 | source = "registry+https://github.com/rust-lang/crates.io-index" 1336 | dependencies = [ 1337 | "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 1338 | "hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 1339 | "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", 1340 | "once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 1341 | "pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 1342 | "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", 1343 | "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", 1344 | ] 1345 | 1346 | [[package]] 1347 | name = "tiny-hderive" 1348 | version = "0.1.0" 1349 | source = "registry+https://github.com/rust-lang/crates.io-index" 1350 | dependencies = [ 1351 | "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1352 | "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", 1353 | "libsecp256k1 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 1354 | "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", 1355 | ] 1356 | 1357 | [[package]] 1358 | name = "tiny-keccak" 1359 | version = "1.5.0" 1360 | source = "registry+https://github.com/rust-lang/crates.io-index" 1361 | dependencies = [ 1362 | "crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 1363 | ] 1364 | 1365 | [[package]] 1366 | name = "toml" 1367 | version = "0.5.3" 1368 | source = "registry+https://github.com/rust-lang/crates.io-index" 1369 | dependencies = [ 1370 | "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", 1371 | ] 1372 | 1373 | [[package]] 1374 | name = "typenum" 1375 | version = "1.11.2" 1376 | source = "registry+https://github.com/rust-lang/crates.io-index" 1377 | 1378 | [[package]] 1379 | name = "uint" 1380 | version = "0.4.1" 1381 | source = "registry+https://github.com/rust-lang/crates.io-index" 1382 | dependencies = [ 1383 | "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 1384 | "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 1385 | "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 1386 | "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1387 | ] 1388 | 1389 | [[package]] 1390 | name = "unicode-xid" 1391 | version = "0.1.0" 1392 | source = "registry+https://github.com/rust-lang/crates.io-index" 1393 | 1394 | [[package]] 1395 | name = "unicode-xid" 1396 | version = "0.2.0" 1397 | source = "registry+https://github.com/rust-lang/crates.io-index" 1398 | 1399 | [[package]] 1400 | name = "unreachable" 1401 | version = "1.0.0" 1402 | source = "registry+https://github.com/rust-lang/crates.io-index" 1403 | dependencies = [ 1404 | "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1405 | ] 1406 | 1407 | [[package]] 1408 | name = "version_check" 1409 | version = "0.1.5" 1410 | source = "registry+https://github.com/rust-lang/crates.io-index" 1411 | 1412 | [[package]] 1413 | name = "void" 1414 | version = "1.0.2" 1415 | source = "registry+https://github.com/rust-lang/crates.io-index" 1416 | 1417 | [[package]] 1418 | name = "walkdir" 1419 | version = "2.2.9" 1420 | source = "registry+https://github.com/rust-lang/crates.io-index" 1421 | dependencies = [ 1422 | "same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", 1423 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 1424 | "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 1425 | ] 1426 | 1427 | [[package]] 1428 | name = "wasi" 1429 | version = "0.7.0" 1430 | source = "registry+https://github.com/rust-lang/crates.io-index" 1431 | 1432 | [[package]] 1433 | name = "winapi" 1434 | version = "0.3.8" 1435 | source = "registry+https://github.com/rust-lang/crates.io-index" 1436 | dependencies = [ 1437 | "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1438 | "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1439 | ] 1440 | 1441 | [[package]] 1442 | name = "winapi-i686-pc-windows-gnu" 1443 | version = "0.4.0" 1444 | source = "registry+https://github.com/rust-lang/crates.io-index" 1445 | 1446 | [[package]] 1447 | name = "winapi-util" 1448 | version = "0.1.2" 1449 | source = "registry+https://github.com/rust-lang/crates.io-index" 1450 | dependencies = [ 1451 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 1452 | ] 1453 | 1454 | [[package]] 1455 | name = "winapi-x86_64-pc-windows-gnu" 1456 | version = "0.4.0" 1457 | source = "registry+https://github.com/rust-lang/crates.io-index" 1458 | 1459 | [[package]] 1460 | name = "zeroize" 1461 | version = "0.9.3" 1462 | source = "registry+https://github.com/rust-lang/crates.io-index" 1463 | 1464 | [[package]] 1465 | name = "zeroize" 1466 | version = "1.0.0" 1467 | source = "registry+https://github.com/rust-lang/crates.io-index" 1468 | 1469 | [metadata] 1470 | "checksum adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" 1471 | "checksum aes-ctr 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d2e5b0458ea3beae0d1d8c0f3946564f8e10f90646cf78c06b4351052058d1ee" 1472 | "checksum aes-soft 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cfd7e7ae3f9a1fb5c03b389fc6bb9a51400d0c13053f0dca698c832bfd893a0d" 1473 | "checksum aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f70a6b5f971e473091ab7cfb5ffac6cde81666c4556751d8d5620ead8abf100" 1474 | "checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" 1475 | "checksum anyhow 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)" = "d9a60d744a80c30fcb657dfe2c1b22bcb3e814c1a1e3674f32bf5820b570fbff" 1476 | "checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" 1477 | "checksum arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" 1478 | "checksum ascii 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e" 1479 | "checksum autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875" 1480 | "checksum backtrace 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)" = "690a62be8920ccf773ee00ef0968649b0e724cda8bd5b12286302b4ae955fdf5" 1481 | "checksum backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "82a830b4ef2d1124a711c71d263c5abdc710ef8e907bd508c88be475cebc422b" 1482 | "checksum base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83" 1483 | "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" 1484 | "checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" 1485 | "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" 1486 | "checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" 1487 | "checksum block-buffer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1339a1042f5d9f295737ad4d9a6ab6bf81c84a933dba110b9200cd6d1448b814" 1488 | "checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" 1489 | "checksum block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c924d49bd09e7c06003acda26cd9742e796e34282ec6c1189404dee0c1f4774" 1490 | "checksum block-padding 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6d4dc3af3ee2e12f3e5d224e5e1e3d73668abbeb69e566d361f7d5563a4fdf09" 1491 | "checksum blockies 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "95ef6d692b1b362f4711aedfbc7e68045e69f34b622e101d90ad4905a2ccc99b" 1492 | "checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" 1493 | "checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" 1494 | "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" 1495 | "checksum c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101" 1496 | "checksum cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)" = "4fc9a35e1f4290eb9e5fc54ba6cf40671ed2a2514c3eeb2b2a908dda2ea5a1be" 1497 | "checksum cesu8 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" 1498 | "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 1499 | "checksum clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17" 1500 | "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" 1501 | "checksum combine 3.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680" 1502 | "checksum constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "995a44c877f9212528ccc74b21a232f66ad69001e40ede5bcee2ac9ef2657120" 1503 | "checksum crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18cd2e169ad86297e6bc0ad9aa679aee9daa4f19e8163860faf7c164e4f5a71" 1504 | "checksum crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fedcd6772e37f3da2a9af9bf12ebe046c0dfe657992377b4df982a2b54cd37a9" 1505 | "checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" 1506 | "checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" 1507 | "checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda" 1508 | "checksum crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" 1509 | "checksum crypto-mac 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "779015233ac67d65098614aec748ac1c756ab6677fa2e14cf8b37c08dfed1198" 1510 | "checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" 1511 | "checksum ctr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "022cd691704491df67d25d006fe8eca083098253c4d43516c2206479c58c6736" 1512 | "checksum curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8b7dcd30ba50cdf88b55b033456138b7c0ac4afdc436d82e1b79f370f24cc66d" 1513 | "checksum deflate 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)" = "707b6a7b384888a70c8d2e8650b3e60170dfc6a67bb4aa67b6dfca57af4bedb4" 1514 | "checksum digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e5b29bf156f3f4b3c4f610a25ff69370616ae6e0657d416de22645483e72af0a" 1515 | "checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" 1516 | "checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" 1517 | "checksum error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ab49e9dcb602294bc42f9a7dfc9bc6e936fca4418ea300dbfb84fe16de0b7d9" 1518 | "checksum ethbloom 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a6294da962646baa738414e8e718d1a1f0360a51d92de89ccbf91870418f5360" 1519 | "checksum ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6e742184dc63a01c8ea0637369f8faa27c40f537949908a237f95c05e68d2c96" 1520 | "checksum ethereum-types-serialize 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1873d77b32bc1891a79dad925f2acbc318ee942b38b9110f9dbc5fbeffcea350" 1521 | "checksum ethsign 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b656fefa0b59f41b39000532c69359e927c0f1850186808ccf1586734ac3365f" 1522 | "checksum ethsign-crypto 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4e62e068d05d580a2504f51e2a242a9ea4a0cd2a6ba378e13de390efcc1b1753" 1523 | "checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9" 1524 | "checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08" 1525 | "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" 1526 | "checksum ffi-support 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "087be066eb6e85d7150f0c5400018a32802f99d688b2d3868c526f7bbfe17960" 1527 | "checksum fixed-hash 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "7afe6ce860afb14422711595a7b26ada9ed7de2f43c0b2ab79d09ee196287273" 1528 | "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" 1529 | "checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" 1530 | "checksum generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fceb69994e330afed50c93524be68c42fa898c2d9fd4ee8da03bd7363acd26f2" 1531 | "checksum getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "473a1265acc8ff1e808cd0a1af8cee3c2ee5200916058a2ca113c29f2d903571" 1532 | "checksum hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3bae29b6653b3412c2e71e9d486db9f9df5d701941d86683005efb9f2d28e3da" 1533 | "checksum heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461" 1534 | "checksum hmac 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7a13f4163aa0c5ca1be584aace0e2212b2e41be5478218d4f657f5f778b2ae2a" 1535 | "checksum hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" 1536 | "checksum hmac-drbg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4fe727d41d2eec0a6574d887914347e5ff96a3b87177817e2a9820c5c87fecc2" 1537 | "checksum hmac-drbg 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c6e570451493f10f6581b48cdd530413b63ea9e780f544bfd3bdcaa0d89d1a7b" 1538 | "checksum hsl 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "575fb7f1167f3b88ed825e90eb14918ac460461fdeaa3965c6a50951dee1c970" 1539 | "checksum inflate 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1cdb29978cc5797bd8dcc8e5bf7de604891df2a8dc576973d71a281e916db2ff" 1540 | "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" 1541 | "checksum jni 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "22bbdc25b49340bc4fc3d9c96dd84d878c4beeca35e3651efa53db51a68d7d4d" 1542 | "checksum jni-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" 1543 | "checksum keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" 1544 | "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 1545 | "checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba" 1546 | "checksum libsecp256k1 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "688e8d65e495567c2c35ea0001b26b9debf0b4ea11f8cccc954233b75fc3428a" 1547 | "checksum libsecp256k1 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "63cc09b49bf0cc55885982347b174ad89855e97a12284d2c9dcc6da2e20c28f5" 1548 | "checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" 1549 | "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" 1550 | "checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" 1551 | "checksum memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce6075db033bbbb7ee5a0bbd3a3186bbae616f57fb001c485c7ff77955f8177f" 1552 | "checksum merlin 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "de2d16d3b15fec5943d1144f861f61f279d165fdd60998ca262913b9bf1c8adb" 1553 | "checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" 1554 | "checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09" 1555 | "checksum num-iter 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "76bd5272412d173d6bf9afdf98db8612bbabc9a7a830b7bfc9c188911716132e" 1556 | "checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32" 1557 | "checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273" 1558 | "checksum once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "532c29a261168a45ce28948f9537ddd7a5dd272cc513b3017b1e82a88f962c37" 1559 | "checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" 1560 | "checksum parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "001fbbb956d8593f321c7a784f64d16b2c99b2657823976eea729006ad2c3668" 1561 | "checksum parity-scale-codec-derive 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "42af752f59119656fa3cb31e8852ed24e895b968c0bdb41847da7f0cea6d155f" 1562 | "checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" 1563 | "checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" 1564 | "checksum pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9" 1565 | "checksum pixelate 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fc05514ca9f4fb3d6f6cbc619c7aa11967ca41808a8b409e688fd88157977c5" 1566 | "checksum png 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "63daf481fdd0defa2d1d2be15c674fbfa1b0fd71882c303a91f9a79b3252c359" 1567 | "checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b" 1568 | "checksum proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" 1569 | "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" 1570 | "checksum proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "90cf5f418035b98e655e9cdb225047638296b862b42411c4e45bb88d700f7fc0" 1571 | "checksum qrcodegen 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1f8c8bc87d0b772361da205f39240d8d61f7ad145d176c38e0ea59e7e6e162b" 1572 | "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" 1573 | "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" 1574 | "checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" 1575 | "checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" 1576 | "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" 1577 | "checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412" 1578 | "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" 1579 | "checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" 1580 | "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" 1581 | "checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" 1582 | "checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" 1583 | "checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" 1584 | "checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" 1585 | "checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" 1586 | "checksum rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" 1587 | "checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" 1588 | "checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" 1589 | "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" 1590 | "checksum rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "83a27732a533a1be0a0035a111fe76db89ad312f6f0347004c220c57f209a123" 1591 | "checksum rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "98dcf634205083b17d0861252431eb2acbfb698ab7478a2d20de07954f47ec7b" 1592 | "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" 1593 | "checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd" 1594 | "checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716" 1595 | "checksum rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16d1effe9845d54f90e7be8420ee49e5c94623140b97ee4bc6fb5bfddb745720" 1596 | "checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" 1597 | "checksum rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "403bb3a286107a04825a5f82e1270acc1e14028d3d554d7a1e08914549575ab8" 1598 | "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" 1599 | "checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" 1600 | "checksum safemem 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d2b08423011dae9a5ca23f07cf57dac3857f5c885d352b76f6d95f4aea9434d0" 1601 | "checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421" 1602 | "checksum schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "eacd8381b3c37840c9c9f40472af529e49975bdcbc24f83c31059fd6539023d3" 1603 | "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" 1604 | "checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" 1605 | "checksum scrypt 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "656c79d0e90d0ab28ac86bf3c3d10bfbbac91450d3f190113b4e76d9fec3cfdd" 1606 | "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" 1607 | "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" 1608 | "checksum serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "9796c9b7ba2ffe7a9ce53c2287dfc48080f4b2b362fcc245a259b3a7201119dd" 1609 | "checksum serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "4b133a43a1ecd55d4086bd5b4dc6c1751c68b1bfbeba7a5040442022c7e7c02e" 1610 | "checksum serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "2f72eb2a68a7dc3f9a691bfda9305a1c017a6215e5a4545c258500d2099a37c2" 1611 | "checksum sha2 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d963c78ce367df26d7ea8b8cc655c651b42e8a1e584e869c1e17dae3ccb116a" 1612 | "checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d" 1613 | "checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7" 1614 | "checksum stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8131256a5896cabcf5eb04f4d6dacbe1aefda854b0d9896e09cb58829ec5638c" 1615 | "checksum substrate-bip39 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3be511be555a3633e71739a79e4ddff6a6aaa6579fa6114182a51d72c3eb93c5" 1616 | "checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" 1617 | "checksum subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab3af2eb31c42e8f0ccf43548232556c42737e01a96db6e1777b0be108e79799" 1618 | "checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" 1619 | "checksum syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "dff0acdb207ae2fe6d5976617f887eb1e35a2ba52c13c7234c790960cdad9238" 1620 | "checksum synstructure 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3f085a5855930c0441ca1288cf044ea4aecf4f43a91668abdb870b4ba546a203" 1621 | "checksum thiserror 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "f0570dc61221295909abdb95c739f2e74325e14293b2026b0a7e195091ec54ae" 1622 | "checksum thiserror-impl 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "227362df41d566be41a28f64401e07a043157c21c14b9785a0d8e256f940a8fd" 1623 | "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" 1624 | "checksum tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c1c5676413eaeb1ea35300a0224416f57abc3bd251657e0fafc12c47ff98c060" 1625 | "checksum tiny-hderive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "61b93055d985b003d5f982ef03088f1a5597bb85b9e0b00efac1b36c18a6cb93" 1626 | "checksum tiny-keccak 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d8a021c69bb74a44ccedb824a046447e2c84a01df9e5c20779750acb38e11b2" 1627 | "checksum toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c7aabe75941d914b72bf3e5d3932ed92ce0664d49d8432305a8b547c37227724" 1628 | "checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9" 1629 | "checksum uint 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "754ba11732b9161b94c41798e5197e5e75388d012f760c42adb5000353e98646" 1630 | "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" 1631 | "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" 1632 | "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" 1633 | "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" 1634 | "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" 1635 | "checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e" 1636 | "checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" 1637 | "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" 1638 | "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1639 | "checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" 1640 | "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1641 | "checksum zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "45af6a010d13e4cf5b54c94ba5a2b2eba5596b9e46bf5875612d332a1f2b3f86" 1642 | "checksum zeroize 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cdc979d9b5ead18184c357c4d8a3f81b579aae264e32507223032e64715462d3" 1643 | -------------------------------------------------------------------------------- /rust/signer/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "signer" 3 | version = "0.1.0" 4 | authors = ["debris "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | base58 = "0.1.0" 9 | base64 = "0.10.1" 10 | blake2-rfc = "0.2.18" 11 | blockies = "0.3" 12 | ethsign = { version = "0.7.3", default-features = false, features = ["pure-rust"] } 13 | jni = { version = "0.16.0", optional = true } 14 | lazy_static = "1.3.0" 15 | libc = "0.2" 16 | codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } 17 | regex = "1.2.1" 18 | rlp = { version = "0.3.0", features = ["ethereum"] } 19 | rustc-hex = "2.0.1" 20 | schnorrkel = "0.8.5" 21 | serde = "1.0" 22 | serde_json = "1.0" 23 | substrate-bip39 = "0.3.1" 24 | tiny-bip39 = { version = "0.6.1", default-features = false } 25 | tiny-hderive = "0.1" 26 | tiny-keccak = "1.4" 27 | pixelate = "0.1" 28 | qrcodegen = "1.4" 29 | thiserror = "1.0" 30 | anyhow = "1.0" 31 | ffi-support = "0.4" 32 | 33 | [lib] 34 | name = "signer" 35 | crate-type = ["staticlib", "cdylib"] 36 | 37 | [features] 38 | default = ["jni"] 39 | -------------------------------------------------------------------------------- /rust/signer/src/eth.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2020 Parity Technologies (UK) Ltd. 2 | // This file is part of Parity. 3 | 4 | // Parity is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | 9 | // Parity is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | 14 | // You should have received a copy of the GNU General Public License 15 | // along with Parity. If not, see . 16 | 17 | //! Ethereum key utils 18 | 19 | use bip39::{Language, Mnemonic, Seed}; 20 | use ethsign::{Error, PublicKey, SecretKey}; 21 | use tiny_hderive::bip32::ExtendedPrivKey; 22 | use tiny_keccak::keccak256; 23 | 24 | pub struct KeyPair { 25 | secret: SecretKey, 26 | public: PublicKey, 27 | } 28 | 29 | pub enum PhraseKind { 30 | Bip39, 31 | Legacy, 32 | } 33 | 34 | impl KeyPair { 35 | pub fn from_secret(secret: SecretKey) -> KeyPair { 36 | let public = secret.public(); 37 | 38 | KeyPair { secret, public } 39 | } 40 | 41 | pub fn from_parity_phrase(phrase: &str) -> KeyPair { 42 | let mut secret = keccak256(phrase.as_bytes()); 43 | let mut i = 0; 44 | 45 | loop { 46 | secret = keccak256(&secret); 47 | 48 | match i > 16384 { 49 | false => i += 1, 50 | true => { 51 | if let Ok(pair) = SecretKey::from_raw(&secret).map(KeyPair::from_secret) { 52 | if pair.public().address()[0] == 0 { 53 | return pair; 54 | } 55 | } 56 | } 57 | } 58 | } 59 | } 60 | 61 | pub fn from_bip39_phrase(phrase: &str) -> Option { 62 | let mnemonic = Mnemonic::from_phrase(phrase, Language::English).ok()?; 63 | let seed = Seed::new(&mnemonic, ""); 64 | let epriv = ExtendedPrivKey::derive(seed.as_bytes(), "m/44'/60'/0'/0/0").ok()?; 65 | 66 | SecretKey::from_raw(&epriv.secret()) 67 | .map(KeyPair::from_secret) 68 | .ok() 69 | } 70 | 71 | pub fn from_auto_phrase(phrase: &str) -> (PhraseKind, KeyPair) { 72 | Self::from_bip39_phrase(phrase) 73 | .map(|keypair| (PhraseKind::Bip39, keypair)) 74 | .unwrap_or_else(|| (PhraseKind::Legacy, Self::from_parity_phrase(phrase))) 75 | } 76 | 77 | pub fn secret(&self) -> &SecretKey { 78 | &self.secret 79 | } 80 | 81 | pub fn public(&self) -> &PublicKey { 82 | &self.public 83 | } 84 | 85 | pub fn address(&self) -> &[u8; 20] { 86 | self.public().address() 87 | } 88 | 89 | pub fn sign(&self, message: &[u8]) -> Result<[u8; 65], Error> { 90 | let signature = self.secret().sign(message)?; 91 | 92 | let mut data: [u8; 65] = [0; 65]; 93 | 94 | data[0..32].copy_from_slice(&signature.r); 95 | data[32..64].copy_from_slice(&signature.s); 96 | data[64] = signature.v; 97 | 98 | Ok(data) 99 | } 100 | } 101 | 102 | #[cfg(test)] 103 | mod tests { 104 | use super::*; 105 | 106 | #[test] 107 | fn test_bip39_phrase() { 108 | let phrase = "panda eyebrow bullet gorilla call smoke muffin taste mesh discover soft ostrich alcohol speed nation flash devote level hobby quick inner drive ghost inside"; 109 | let expected_address = 110 | b"\x63\xF9\xA9\x2D\x8D\x61\xb4\x8a\x9f\xFF\x8d\x58\x08\x04\x25\xA3\x01\x2d\x05\xC8"; 111 | 112 | let keypair = KeyPair::from_bip39_phrase(phrase).unwrap(); 113 | 114 | assert_eq!(keypair.address(), expected_address); 115 | } 116 | 117 | #[test] 118 | fn test_parity_phrase() { 119 | let phrase = "this is sparta"; 120 | let expected_address = 121 | b"\x00\x6E\x27\xB6\xA7\x2E\x1f\x34\xC6\x26\x76\x2F\x3C\x47\x61\x54\x7A\xff\x14\x21"; 122 | 123 | let keypair = KeyPair::from_parity_phrase(phrase); 124 | 125 | assert_eq!(keypair.address(), expected_address); 126 | } 127 | 128 | #[test] 129 | fn test_parity_empty_phrase() { 130 | let phrase = ""; 131 | let expected_address = 132 | b"\x00\xa3\x29\xc0\x64\x87\x69\xA7\x3a\xfA\xc7\xF9\x38\x1E\x08\xFB\x43\xdB\xEA\x72"; 133 | 134 | let keypair = KeyPair::from_parity_phrase(phrase); 135 | 136 | assert_eq!(keypair.address(), expected_address); 137 | } 138 | 139 | #[test] 140 | fn test_auto_bip39_phrase() { 141 | let phrase = "panda eyebrow bullet gorilla call smoke muffin taste mesh discover soft ostrich alcohol speed nation flash devote level hobby quick inner drive ghost inside"; 142 | let expected_address = 143 | b"\x63\xF9\xA9\x2D\x8D\x61\xb4\x8a\x9f\xFF\x8d\x58\x08\x04\x25\xA3\x01\x2d\x05\xC8"; 144 | 145 | let (_, keypair) = KeyPair::from_auto_phrase(phrase); 146 | 147 | assert_eq!(keypair.address(), expected_address); 148 | } 149 | 150 | #[test] 151 | fn test_auto_parity_phrase() { 152 | let phrase = "this is sparta"; 153 | let expected_address = 154 | b"\x00\x6E\x27\xB6\xA7\x2E\x1f\x34\xC6\x26\x76\x2F\x3C\x47\x61\x54\x7A\xff\x14\x21"; 155 | 156 | let (_, keypair) = KeyPair::from_auto_phrase(phrase); 157 | 158 | assert_eq!(keypair.address(), expected_address); 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /rust/signer/src/export/android/arg.rs: -------------------------------------------------------------------------------- 1 | use crate::export::Argument; 2 | use jni::objects::JString; 3 | use jni::sys::{jboolean, jint, jlong}; 4 | use jni::JNIEnv; 5 | 6 | impl<'a> Argument<'a> for u32 { 7 | type Ext = jint; 8 | type Env = JNIEnv<'a>; 9 | fn convert(_: &Self::Env, val: Self::Ext) -> Self { 10 | val as u32 11 | } 12 | } 13 | 14 | impl<'a> Argument<'a> for i64 { 15 | type Ext = jlong; 16 | type Env = JNIEnv<'a>; 17 | fn convert(_: &Self::Env, val: Self::Ext) -> Self { 18 | val as i64 19 | } 20 | } 21 | 22 | impl<'a> Argument<'a> for u8 { 23 | type Ext = jint; 24 | type Env = JNIEnv<'a>; 25 | fn convert(_: &Self::Env, val: Self::Ext) -> Self { 26 | val as u8 27 | } 28 | } 29 | 30 | impl<'a> Argument<'a> for bool { 31 | type Ext = jboolean; 32 | type Env = JNIEnv<'a>; 33 | fn convert(_: &Self::Env, val: Self::Ext) -> Self { 34 | val != 0 35 | } 36 | } 37 | 38 | impl<'jni, 'a> Argument<'jni> for &'a str { 39 | type Ext = JString<'jni>; 40 | type Env = JNIEnv<'jni>; 41 | fn convert(env: &Self::Env, val: Self::Ext) -> Self { 42 | use std::ffi::CStr; 43 | use std::str; 44 | unsafe { 45 | let ptr = env.get_string_utf_chars(val).expect("Invalid java string"); 46 | let slice = CStr::from_ptr(ptr).to_bytes(); 47 | str::from_utf8_unchecked(slice) 48 | } 49 | } 50 | } 51 | 52 | impl<'a> Argument<'a> for String { 53 | type Ext = JString<'a>; 54 | type Env = JNIEnv<'a>; 55 | fn convert(env: &Self::Env, val: Self::Ext) -> Self { 56 | env.get_string(val).expect("Invalid java string").into() 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /rust/signer/src/export/android/mod.rs: -------------------------------------------------------------------------------- 1 | mod arg; 2 | mod ret; 3 | 4 | pub use arg::*; 5 | pub use ret::*; 6 | -------------------------------------------------------------------------------- /rust/signer/src/export/android/ret.rs: -------------------------------------------------------------------------------- 1 | use crate::export::Return; 2 | use jni::objects::JThrowable; 3 | use jni::sys::{jboolean, jlong, jstring, JNI_FALSE}; 4 | use jni::JNIEnv; 5 | 6 | impl<'a> Return<'a> for () { 7 | type Ext = jboolean; 8 | type Env = &'a JNIEnv<'a>; 9 | fn convert(_: Self::Env, _val: Self) -> Self::Ext { 10 | JNI_FALSE 11 | } 12 | } 13 | 14 | impl<'a> Return<'a> for i64 { 15 | type Ext = jlong; 16 | type Env = &'a JNIEnv<'a>; 17 | fn convert(_: Self::Env, val: Self) -> Self::Ext { 18 | val as Self::Ext 19 | } 20 | } 21 | 22 | impl<'a> Return<'a> for bool { 23 | type Ext = jboolean; 24 | type Env = &'a JNIEnv<'a>; 25 | fn convert(_: Self::Env, val: Self) -> Self::Ext { 26 | val as Self::Ext 27 | } 28 | } 29 | 30 | impl<'a> Return<'a> for String { 31 | type Ext = jstring; 32 | type Env = &'a JNIEnv<'a>; 33 | fn convert(env: Self::Env, val: Self) -> Self::Ext { 34 | env.new_string(val) 35 | .expect("Could not create java string") 36 | .into_inner() 37 | } 38 | } 39 | 40 | impl<'a, Inner: Return<'a, Env = &'a JNIEnv<'a>> + Default> Return<'a> for Option { 41 | type Ext = Inner::Ext; 42 | type Env = Inner::Env; 43 | 44 | fn convert(env: Self::Env, val: Self) -> Self::Ext { 45 | match val { 46 | Some(inner) => Return::convert(env, inner), 47 | None => { 48 | // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 49 | // !!!! !!!! 50 | // !!!! RETURN VALUE HAS TO BE CREATED BEFORE THROWING THE EXCEPTION !!!! 51 | // !!!! !!!! 52 | // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 53 | let ret = Return::convert_without_exception(env, Inner::default()); 54 | let class = env 55 | .find_class("java/lang/Exception") 56 | .expect("Must have the Exception class; qed"); 57 | let exception: JThrowable<'a> = env 58 | .new_object(class, "()V", &[]) 59 | .expect("Must be able to instantiate the Exception; qed") 60 | .into(); 61 | // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 62 | // !!!! !!!! 63 | // !!!! WE CAN NO LONGER INTERACT WITH JNIENV AFTER THROWING !!!! 64 | // !!!! !!!! 65 | // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 66 | env.throw(exception) 67 | .expect("Must be able to throw the Exception; qed"); 68 | ret 69 | } 70 | } 71 | } 72 | 73 | fn convert_without_exception(env: Self::Env, val: Self) -> Self::Ext { 74 | match val { 75 | Some(inner) => Return::convert_without_exception(env, inner), 76 | None => Return::convert_without_exception(env, Inner::default()), 77 | } 78 | } 79 | } 80 | 81 | impl<'a, Inner, D> Return<'a> for Result 82 | where 83 | Inner: Return<'a, Env = &'a JNIEnv<'a>> + Default, 84 | D: core::fmt::Debug, 85 | { 86 | type Ext = Inner::Ext; 87 | type Env = Inner::Env; 88 | 89 | fn convert(env: Self::Env, val: Self) -> Self::Ext { 90 | match val { 91 | Ok(inner) => Return::convert(env, inner), 92 | Err(e) => { 93 | // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 94 | // !!!! !!!! 95 | // !!!! RETURN VALUE HAS TO BE CREATED BEFORE THROWING THE EXCEPTION !!!! 96 | // !!!! !!!! 97 | // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 98 | let ret = Return::convert_without_exception(env, Inner::default()); 99 | // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 100 | // !!!! !!!! 101 | // !!!! WE CAN NO LONGER INTERACT WITH JNIENV AFTER THROWING !!!! 102 | // !!!! !!!! 103 | // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 104 | env.throw(format!("testing 123 {:?}", e)) 105 | .expect("Must be able to throw the Exception; qed"); 106 | ret 107 | } 108 | } 109 | } 110 | 111 | fn convert_without_exception(env: Self::Env, val: Self) -> Self::Ext { 112 | match val { 113 | Ok(inner) => Return::convert(env, inner), 114 | Err(_) => Return::convert_without_exception(env, Inner::default()), 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /rust/signer/src/export/android/util.rs: -------------------------------------------------------------------------------- 1 | use super::result::*; 2 | 3 | use jni::objects::JObject; 4 | use jni::strings::JNIString; 5 | use jni::sys::jsize; 6 | use jni::JNIEnv; 7 | use jni_glue::{ByteArray, Local, ObjectArray}; 8 | 9 | use android::content::{Context, Intent}; 10 | use android::security::keystore::{ 11 | KeyGenParameterSpec, KeyGenParameterSpec_Builder, KeyProperties, 12 | }; 13 | use android::util::Base64; 14 | use java::lang::{CharSequence, Throwable}; 15 | use java::security::spec::AlgorithmParameterSpec; 16 | use java::security::{Key, KeyStore}; 17 | use javax::crypto::spec::IvParameterSpec; 18 | use javax::crypto::{Cipher, KeyGenerator, SecretKey}; 19 | use jni_android_sys::*; 20 | 21 | pub type JavaString = java::lang::String; 22 | 23 | pub fn java_string<'a, S>(env: &'a JNIEnv, s: &S) -> Local<'a, JavaString> 24 | where 25 | S: Into + std::fmt::Debug + std::convert::AsRef, 26 | { 27 | unsafe { 28 | Local::from_env_object( 29 | env.get_native_interface(), 30 | env.new_string(s) 31 | .expect(&format!("Creating java string for '{:?}'", s)) 32 | .into_inner(), 33 | ) 34 | } 35 | } 36 | 37 | pub fn java_string_array<'a>( 38 | env: &'a JNIEnv, 39 | size: jsize, 40 | ) -> Result>> { 41 | unsafe { 42 | let class = env 43 | .find_class("java/lang/String") 44 | .map_err(|e| e.description().to_string())?; 45 | let object = env 46 | .new_object_array(size, class, JObject::null()) 47 | .map_err(|e| e.description().to_string())?; 48 | let exception = env 49 | .exception_occurred() 50 | .map_err(|e| e.description().to_string())?; 51 | assert!(exception.is_null()); // Only sane exception here is an OOM exception 52 | Ok(Local::from_env_object(env.get_native_interface(), object)) 53 | } 54 | } 55 | 56 | pub fn java_key_generator<'a>( 57 | env: &'a JNIEnv, 58 | algorithm: &'a JavaString, 59 | provider: &'a JavaString, 60 | ) -> Result> { 61 | resopt!(KeyGenerator::getInstance_String_String( 62 | unsafe { jni_glue::Env::from_ptr(env.get_native_interface()) }, 63 | Some(algorithm), 64 | Some(provider) 65 | )) 66 | } 67 | 68 | pub fn java_algorithm_parameter_spec<'a>( 69 | env: &'a JNIEnv, 70 | alias: &'a JavaString, 71 | block_mode: &'a ObjectArray, 72 | padding: &'a ObjectArray, 73 | key_size: i32, 74 | with_biometry: bool, 75 | ) -> Result> { 76 | let x: Local<'a, KeyGenParameterSpec_Builder> = 77 | stringify_throwable!(KeyGenParameterSpec_Builder::new( 78 | unsafe { jni_glue::Env::from_ptr(env.get_native_interface()) }, 79 | alias, 80 | KeyProperties::PURPOSE_ENCRYPT | KeyProperties::PURPOSE_DECRYPT, 81 | ))?; 82 | r#try!(resopt!(x.setKeySize(key_size))); 83 | r#try!(resopt!(x.setBlockModes(Some(&*block_mode)))); 84 | r#try!(resopt!(x.setEncryptionPaddings(Some(&*padding)))); 85 | r#try!(resopt!(x.setRandomizedEncryptionRequired(true))); // indistinguishability under chosen-plaintext attack (IND-CPA) 86 | if with_biometry { 87 | r#try!(resopt!(x.setUserAuthenticationRequired(true))); // requires biometric auth before every key use; at least one fingerprint must be enrolled 88 | } else { 89 | r#try!(resopt!(x.setUserAuthenticationRequired(false))); 90 | } 91 | // r#try!(resopt!(x.setInvalidatedByBiometricEnrollment(false))); // defaults to true 92 | let built = r#try!(resopt!(x.build())); 93 | Ok(unsafe { 94 | std::mem::transmute::, Local<'_, AlgorithmParameterSpec>>( 95 | built, 96 | ) 97 | }) 98 | } 99 | 100 | pub fn java_algorithm_parameter_spec_from_bytes<'a>( 101 | env: &'a JNIEnv, 102 | iv: &'a ByteArray, 103 | ) -> Result> { 104 | let spec = stringify_throwable!(IvParameterSpec::new_byte_array( 105 | unsafe { jni_glue::Env::from_ptr(env.get_native_interface()) }, 106 | Some(iv) 107 | ))?; 108 | Ok(unsafe { 109 | std::mem::transmute::, Local<'_, AlgorithmParameterSpec>>(spec) 110 | }) 111 | } 112 | 113 | pub fn java_generate_key<'a>(keygen: &'a KeyGenerator) -> Result> { 114 | let key = r#try!(resopt!(keygen.generateKey())); 115 | Ok(unsafe { std::mem::transmute::, Local<'_, Key>>(key) }) 116 | } 117 | 118 | pub fn java_cipher<'a>( 119 | env: &'a JNIEnv, 120 | transform: &'a JavaString, 121 | mode: i32, 122 | secret_key: Local<'a, Key>, 123 | spec: Option<&'a AlgorithmParameterSpec>, 124 | ) -> Result> { 125 | let cipher = r#try!(resopt!(Cipher::getInstance_String( 126 | unsafe { jni_glue::Env::from_ptr(env.get_native_interface()) }, 127 | transform 128 | ))); 129 | let _ = stringify_throwable!(cipher.init_int_Key_AlgorithmParameterSpec( 130 | mode, 131 | Some(&*secret_key), 132 | spec 133 | ))?; 134 | Ok(cipher) 135 | } 136 | 137 | pub fn java_base64_encode<'a>( 138 | env: &'a JNIEnv, 139 | bytes: &'a ByteArray, 140 | ) -> Result> { 141 | resopt!(Base64::encodeToString_byte_array_int( 142 | unsafe { jni_glue::Env::from_ptr(env.get_native_interface()) }, 143 | Some(bytes), 144 | Base64::DEFAULT 145 | )) 146 | } 147 | 148 | pub fn java_base64_decode<'a>(env: &'a JNIEnv, s: &'a JavaString) -> Result> { 149 | resopt!(Base64::decode_String_int( 150 | unsafe { jni_glue::Env::from_ptr(env.get_native_interface()) }, 151 | Some(s), 152 | Base64::DEFAULT 153 | )) 154 | } 155 | 156 | pub fn java_context<'a>(env: &'a JNIEnv, activity: &'a JObject) -> Local<'a, Context> { 157 | unsafe { Local::from_env_object(env.get_native_interface(), activity.into_inner()) } 158 | } 159 | 160 | pub fn java_keystore<'a>(env: &'a JNIEnv, provider: &'a JavaString) -> Result> { 161 | resopt!(KeyStore::getInstance_String( 162 | unsafe { jni_glue::Env::from_ptr(env.get_native_interface()) }, 163 | provider 164 | )) 165 | } 166 | -------------------------------------------------------------------------------- /rust/signer/src/export/ios/arg.rs: -------------------------------------------------------------------------------- 1 | use super::super::Argument; 2 | use ffi_support::{ExternError, FfiStr}; 3 | use libc::c_char; 4 | 5 | impl Argument<'static> for i64 { 6 | type Ext = i64; 7 | type Env = &'static mut ExternError; 8 | fn convert(_: &Self::Env, val: Self::Ext) -> Self { 9 | val 10 | } 11 | } 12 | 13 | impl Argument<'static> for u32 { 14 | type Ext = u32; 15 | type Env = &'static mut ExternError; 16 | fn convert(_: &Self::Env, val: Self::Ext) -> Self { 17 | val 18 | } 19 | } 20 | 21 | impl Argument<'static> for u8 { 22 | type Ext = u32; 23 | type Env = &'static mut ExternError; 24 | fn convert(_: &Self::Env, val: Self::Ext) -> Self { 25 | val as u8 26 | } 27 | } 28 | 29 | impl Argument<'static> for bool { 30 | type Ext = u8; 31 | type Env = &'static mut ExternError; 32 | fn convert(_: &Self::Env, val: Self::Ext) -> Self { 33 | val != 0 34 | } 35 | } 36 | 37 | impl<'a> Argument<'static> for &'a str { 38 | type Ext = *const c_char; 39 | type Env = &'static mut ExternError; 40 | fn convert(_: &Self::Env, val: Self::Ext) -> Self { 41 | unsafe { FfiStr::from_raw(val) }.as_str() 42 | } 43 | } 44 | 45 | impl Argument<'static> for String { 46 | type Ext = *const c_char; 47 | type Env = &'static mut ExternError; 48 | fn convert(_: &Self::Env, val: Self::Ext) -> Self { 49 | unsafe { FfiStr::from_raw(val) }.into_string() 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /rust/signer/src/export/ios/mod.rs: -------------------------------------------------------------------------------- 1 | mod arg; 2 | mod ret; 3 | 4 | pub use arg::*; 5 | pub use ret::*; 6 | -------------------------------------------------------------------------------- /rust/signer/src/export/ios/ret.rs: -------------------------------------------------------------------------------- 1 | use super::super::Return; 2 | use ffi_support::{rust_string_to_c, ErrorCode, ExternError}; 3 | use libc::c_char; 4 | 5 | impl Return<'static> for () { 6 | type Ext = *mut std::ffi::c_void; 7 | type Env = &'static mut ExternError; 8 | fn convert(_: Self::Env, _val: Self) -> Self::Ext { 9 | std::ptr::null_mut() 10 | } 11 | } 12 | 13 | impl Return<'static> for i64 { 14 | type Ext = i64; 15 | type Env = &'static mut ExternError; 16 | fn convert(_: Self::Env, val: Self) -> Self::Ext { 17 | val 18 | } 19 | } 20 | 21 | impl Return<'static> for bool { 22 | type Ext = u8; 23 | type Env = &'static mut ExternError; 24 | fn convert(_: Self::Env, val: Self) -> Self::Ext { 25 | val as u8 26 | } 27 | } 28 | 29 | impl Return<'static> for String { 30 | type Ext = *mut c_char; 31 | type Env = &'static mut ExternError; 32 | fn convert(_: Self::Env, val: Self) -> Self::Ext { 33 | rust_string_to_c(val) 34 | } 35 | } 36 | 37 | impl + Default> Return<'static> 38 | for anyhow::Result 39 | { 40 | type Ext = Inner::Ext; 41 | type Env = Inner::Env; 42 | fn convert(env: Self::Env, val: Self) -> Self::Ext { 43 | let val = match val { 44 | Ok(inner) => inner, 45 | Err(e) => { 46 | *env = ExternError::new_error(ErrorCode::new(1), format!("{:?}", e)); 47 | Inner::default() 48 | } 49 | }; 50 | let ret = Return::convert(env, val); 51 | ret 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /rust/signer/src/export/mod.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "jni")] 2 | pub mod android; 3 | #[cfg(not(feature = "jni"))] 4 | pub mod ios; 5 | 6 | pub use anyhow; 7 | pub use ffi_support; 8 | 9 | /// Trait for converting Rust types into FFI return values 10 | pub trait Return<'a>: Sized { 11 | type Ext; 12 | type Env; 13 | fn convert(env: Self::Env, val: Self) -> Self::Ext; 14 | fn convert_without_exception(env: Self::Env, val: Self) -> Self::Ext { 15 | Return::convert(env, val) 16 | } 17 | } 18 | 19 | /// Trait for converting FFI arguments into Rust types 20 | pub trait Argument<'a> { 21 | type Ext; 22 | type Env; 23 | fn convert(env: &Self::Env, val: Self::Ext) -> Self; 24 | } 25 | 26 | #[macro_export] 27 | macro_rules! export { 28 | ($( @$jname:ident fn $name:ident($( $a:ident : $t:ty ),*) -> $ret:ty $code:block )*) => { 29 | $( 30 | pub fn $name( 31 | $( $a: $t ),* 32 | ) -> $ret $code 33 | )* 34 | 35 | #[cfg(feature = "jni")] 36 | pub mod android_export { 37 | use $crate::export::{Return, Argument}; 38 | 39 | use jni::JNIEnv; 40 | use jni::objects::JClass; 41 | 42 | $( 43 | #[no_mangle] 44 | pub extern fn $jname<'jni>( 45 | env: JNIEnv<'jni>, 46 | _: JClass, 47 | $( $a: <$t as Argument<'jni>>::Ext ),* 48 | ) -> <$ret as Return<'jni>>::Ext { 49 | let ret = super::$name($( Argument::convert(&env, $a) ),*); 50 | Return::convert(&env, ret) 51 | } 52 | )* 53 | } 54 | 55 | #[cfg(not(feature = "jni"))] 56 | pub mod ios_export { 57 | use $crate::export::{Return, Argument}; 58 | 59 | use ffi_support::ExternError; 60 | 61 | $( 62 | #[no_mangle] 63 | pub extern "C" fn $name( 64 | err: &'static mut ExternError, 65 | $( $a: <$t as Argument<'static>>::Ext ),* 66 | ) -> <$ret as Return<'static>>::Ext { 67 | let res = super::$name($( Argument::convert(&err, $a) ),*); 68 | let ret = Return::convert(err, res); 69 | ret 70 | } 71 | )* 72 | } 73 | } 74 | } 75 | 76 | #[cfg(test)] 77 | mod tests {} 78 | -------------------------------------------------------------------------------- /rust/signer/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2020 Parity Technologies (UK) Ltd. 2 | // This file is part of Parity. 3 | 4 | // Parity is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | 9 | // Parity is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | 14 | // You should have received a copy of the GNU General Public License 15 | // along with Parity. If not, see . 16 | 17 | use bip39::{Language, Mnemonic, MnemonicType}; 18 | use blake2_rfc::blake2b::blake2b; 19 | use blockies::Ethereum; 20 | use ethsign::{keyfile::Crypto, Protected}; 21 | use pixelate::{Color, Image, BLACK}; 22 | use qrcodegen::{QrCode, QrCodeEcc}; 23 | use rlp::decode_list; 24 | use rustc_hex::{FromHex, ToHex}; 25 | use tiny_keccak::keccak256 as keccak; 26 | use tiny_keccak::Keccak; 27 | 28 | use eth::{KeyPair, PhraseKind}; 29 | use result::{Error, Result}; 30 | 31 | mod eth; 32 | mod export; 33 | mod result; 34 | mod sr25519; 35 | 36 | const CRYPTO_ITERATIONS: u32 = 10240; 37 | 38 | fn base64png(png: &[u8]) -> String { 39 | static HEADER: &str = "data:image/png;base64,"; 40 | let mut out = String::with_capacity(png.len() + png.len() / 2 + HEADER.len()); 41 | out.push_str(HEADER); 42 | base64::encode_config_buf(png, base64::STANDARD, &mut out); 43 | out 44 | } 45 | 46 | fn qrcode_bytes(data: &[u8]) -> crate::Result { 47 | let qr = QrCode::encode_binary(data, QrCodeEcc::Medium)?; 48 | let palette = &[Color::Rgba(255, 255, 255, 0), BLACK]; 49 | let mut pixels = Vec::with_capacity((qr.size() * qr.size()) as usize); 50 | for y in 0..qr.size() { 51 | for x in 0..qr.size() { 52 | pixels.push(qr.get_module(x, y) as u8); 53 | } 54 | } 55 | let mut result = Vec::new(); 56 | Image { 57 | palette, 58 | pixels: &pixels, 59 | width: qr.size() as usize, 60 | scale: 16, 61 | } 62 | .render(&mut result) 63 | .map_err(|e| crate::Error::Pixelate(e))?; 64 | Ok(base64png(&result)) 65 | } 66 | 67 | export! { 68 | @Java_io_parity_substrateSign_SubstrateSignModule_ethkeyBrainwalletAddress 69 | fn ethkey_brainwallet_address( 70 | seed: &str 71 | ) -> String { 72 | let (kind, keypair) = KeyPair::from_auto_phrase(seed); 73 | let mut out = String::with_capacity(47); 74 | out += match kind { 75 | PhraseKind::Bip39 => "bip39:", 76 | PhraseKind::Legacy => "legacy:", 77 | }; 78 | out += &keypair.address().to_hex::(); 79 | out 80 | } 81 | 82 | @Java_io_parity_substrateSign_SubstrateSignModule_ethkeyBrainwalletBIP39Address 83 | fn ethkey_brainwallet_bip39_address( 84 | seed: &str 85 | ) -> crate::Result { 86 | let keypair = KeyPair::from_bip39_phrase(seed) 87 | .ok_or(crate::Error::KeyPairIsNone)?; 88 | Ok(keypair.address().to_hex()) 89 | } 90 | 91 | @Java_io_parity_substrateSign_SubstrateSignModule_ethkeyBrainwalletSign 92 | fn ethkey_brainwallet_sign( 93 | seed: &str, 94 | message: &str 95 | ) -> crate::Result { 96 | let (_, keypair) = KeyPair::from_auto_phrase(seed); 97 | let message: Vec = message.from_hex() 98 | .map_err(|e| crate::Error::FromHex(e))?; 99 | let signature = keypair.sign(&message) 100 | .map_err(|e| crate::Error::Ethsign(e))?; 101 | Ok(signature.to_hex()) 102 | } 103 | 104 | @Java_io_parity_substrateSign_SubstrateSignModule_ethkeyRlpItem 105 | fn rlp_item( 106 | rlp: &str, 107 | position: u32 108 | ) -> crate::Result { 109 | let hex: Vec = rlp.from_hex() 110 | .map_err(|e| crate::Error::FromHex(e))?; 111 | let rlp = decode_list::>(&hex); 112 | rlp.get(position as usize).map(|data| data.to_hex()) 113 | .ok_or(anyhow::anyhow!("index out of bounds")) 114 | } 115 | 116 | @Java_io_parity_substrateSign_SubstrateSignModule_ethkeyKeccak 117 | fn keccak256( 118 | data: &str 119 | ) -> crate::Result { 120 | let data: Vec = data.from_hex() 121 | .map_err(|e| crate::Error::FromHex(e))?; 122 | Ok(keccak(&data).to_hex()) 123 | } 124 | 125 | @Java_io_parity_substrateSign_SubstrateSignModule_ethkeyBlake 126 | fn blake( 127 | data: &str 128 | ) -> crate::Result { 129 | let data: Vec = data.from_hex() 130 | .map_err(|e| crate::Error::FromHex(e))?; 131 | Ok(blake2b(32, &[], &data).as_bytes().to_hex()) 132 | } 133 | 134 | @Java_io_parity_substrateSign_SubstrateSignModule_ethkeyBlockiesIcon 135 | fn blockies_icon( 136 | seed: String 137 | ) -> crate::Result { 138 | let mut result = Vec::new(); 139 | let blockies = Ethereum::default(); 140 | match blockies.create_icon(&mut result, seed.as_bytes()) { 141 | Ok(_) => Ok(base64png(&result)), 142 | Err(e) => Err(crate::Error::Blockies(e).into()), 143 | } 144 | } 145 | 146 | @Java_io_parity_substrateSign_SubstrateSignModule_ethkeyEthSign 147 | fn eth_sign( 148 | data: &str 149 | ) -> crate::Result { 150 | let hex: Vec = data.from_hex() 151 | .map_err(|e| crate::Error::FromHex(e))?; 152 | let message = format!("\x19Ethereum Signed Message:\n{}", hex.len()).into_bytes(); 153 | let mut res = [0u8; 32]; 154 | let mut keccak = Keccak::new_keccak256(); 155 | keccak.update(&message); 156 | keccak.update(&hex); 157 | keccak.finalize(&mut res); 158 | Ok(res.to_hex()) 159 | } 160 | 161 | @Java_io_parity_substrateSign_SubstrateSignModule_ethkeyRandomPhrase 162 | fn random_phrase( 163 | words_number:u32 164 | ) -> String { 165 | let mnemonic_type = match MnemonicType::for_word_count(words_number as usize) { 166 | Ok(t) => t, 167 | Err(_e) => MnemonicType::Words24, 168 | }; 169 | let mnemonic = Mnemonic::new(mnemonic_type, Language::English); 170 | mnemonic.into_phrase() 171 | } 172 | 173 | @Java_io_parity_substrateSign_SubstrateSignModule_ethkeyEncryptData 174 | fn encrypt_data( 175 | data: &str, 176 | password: String 177 | ) -> crate::Result { 178 | let password = Protected::new(password.into_bytes()); 179 | let crypto = Crypto::encrypt(data.as_bytes(), &password, CRYPTO_ITERATIONS) 180 | .map_err(|e| crate::Error::Ethsign(e))?; 181 | Ok(serde_json::to_string(&crypto)?) 182 | } 183 | 184 | @Java_io_parity_substrateSign_SubstrateSignModule_ethkeyDecryptData 185 | fn decrypt_data( 186 | data: &str, 187 | password: String 188 | ) -> crate::Result { 189 | let password = Protected::new(password.into_bytes()); 190 | let crypto: Crypto = serde_json::from_str(data)?; 191 | let decrypted = crypto.decrypt(&password) 192 | .map_err(|e| crate::Error::Ethsign(e))?; 193 | Ok(String::from_utf8(decrypted)?) 194 | } 195 | 196 | @Java_io_parity_substrateSign_SubstrateSignModule_ethkeyQrCode 197 | fn qrcode( 198 | data: &str 199 | ) -> crate::Result { 200 | qrcode_bytes(data.as_bytes()) 201 | } 202 | 203 | @Java_io_parity_substrateSign_SubstrateSignModule_ethkeyQrCodeHex 204 | fn qrcode_hex( 205 | data: &str 206 | ) -> crate::Result { 207 | let bytes = &data.from_hex::>() 208 | .map_err(|e| crate::Error::FromHex(e))?; 209 | qrcode_bytes(&bytes) 210 | } 211 | 212 | @Java_io_parity_substrateSign_SubstrateSignModule_substrateBrainwalletAddress 213 | fn substrate_brainwallet_address( 214 | suri: &str, 215 | prefix: u8 216 | ) -> crate::Result { 217 | let keypair = sr25519::KeyPair::from_suri(suri) 218 | .ok_or(crate::Error::KeyPairIsNone)?; 219 | Ok(keypair.ss58_address(prefix)) 220 | } 221 | 222 | @Java_io_parity_substrateSign_SubstrateSignModule_substrateBrainwalletSign 223 | fn substrate_brainwallet_sign( 224 | suri: &str, 225 | message: &str 226 | ) -> crate::Result { 227 | let keypair = sr25519::KeyPair::from_suri(suri) 228 | .ok_or(crate::Error::KeyPairIsNone)?; 229 | let message: Vec = message.from_hex() 230 | .map_err(|e| crate::Error::FromHex(e))?; 231 | let signature = keypair.sign(&message); 232 | Ok(signature.to_hex()) 233 | } 234 | 235 | @Java_io_parity_substrateSign_SubstrateSignModule_schnorrkelVerify 236 | fn schnorrkel_verify( 237 | suri: &str, 238 | msg: &str, 239 | signature: &str 240 | ) -> crate::Result { 241 | let keypair = sr25519::KeyPair::from_suri(suri) 242 | .ok_or(crate::Error::KeyPairIsNone)?; 243 | let message: Vec = msg.from_hex() 244 | .map_err(|e| crate::Error::FromHex(e))?; 245 | let signature: Vec = signature.from_hex() 246 | .map_err(|e| crate::Error::FromHex(e))?; 247 | keypair.verify_signature(&message, &signature) 248 | } 249 | 250 | @Java_io_parity_substrateSign_SubstrateSignModule_ethkeyDecryptDataRef 251 | fn decrypt_data_ref( 252 | data: &str, 253 | password: String 254 | ) -> crate::Result { 255 | let password = Protected::new(password.into_bytes()); 256 | let crypto: Crypto = serde_json::from_str(data)?; 257 | let decrypted = crypto.decrypt(&password) 258 | .map_err(|e| crate::Error::Ethsign(e))?; 259 | Ok(Box::into_raw(Box::new(String::from_utf8(decrypted).ok())) as i64) 260 | } 261 | 262 | @Java_io_parity_substrateSign_SubstrateSignModule_ethkeyDestroyDataRef 263 | fn destroy_data_ref(data_ref: i64) -> () { 264 | unsafe { Box::from_raw(data_ref as *mut String) }; 265 | } 266 | 267 | @Java_io_parity_substrateSign_SubstrateSignModule_ethkeyBrainwalletSignWithRef 268 | fn ethkey_brainwallet_sign_with_ref( 269 | seed_ref: i64, 270 | message: &str 271 | ) -> crate::Result { 272 | let seed = unsafe { Box::from_raw(seed_ref as *mut String) }; 273 | let (_, keypair) = KeyPair::from_auto_phrase(&seed); 274 | let message: Vec = message.from_hex() 275 | .map_err(|e| crate::Error::FromHex(e))?; 276 | let signature = keypair.sign(&message) 277 | .map_err(|e| crate::Error::Ethsign(e))?; 278 | // so that the reference remains valid 279 | let _ = Box::into_raw(seed) as i64; 280 | Ok(signature.to_hex()) 281 | } 282 | 283 | @Java_io_parity_substrateSign_SubstrateSignModule_ethkeySubstrateBrainwalletSignWithRef 284 | fn substrate_brainwallet_sign_with_ref( 285 | seed_ref: i64, 286 | suri_suffix: &str, 287 | message: &str 288 | ) -> crate::Result { 289 | let seed = unsafe { Box::from_raw(seed_ref as *mut String) }; 290 | let suri = format!("{}{}", &seed, suri_suffix); 291 | let keypair = sr25519::KeyPair::from_suri(&suri) 292 | .ok_or(crate::Error::KeyPairIsNone)?; 293 | let message: Vec = message.from_hex() 294 | .map_err(|e| crate::Error::FromHex(e))?; 295 | let signature = keypair.sign(&message); 296 | // so that the reference remains valid 297 | let _ = Box::into_raw(seed) as i64; 298 | Ok(signature.to_hex()) 299 | } 300 | 301 | @Java_io_parity_substrateSign_SubstrateSignModule_ethkeySubstrateWalletAddressWithRef 302 | fn substrate_address_with_ref( 303 | seed_ref: i64, 304 | suri_suffix: &str, 305 | prefix: u8 306 | ) -> crate::Result { 307 | let seed = unsafe { Box::from_raw(seed_ref as *mut String) }; 308 | let suri = format!("{}{}", &seed, suri_suffix); 309 | let keypair = sr25519::KeyPair::from_suri(&suri) 310 | .ok_or(crate::Error::KeyPairIsNone)?; 311 | // so that the reference remains valid 312 | let _ = Box::into_raw(seed) as i64; 313 | Ok(keypair.ss58_address(prefix)) 314 | } 315 | 316 | @Java_io_parity_substrateSign_SubstrateSignModule_ethkeyBrainWalletAddressWithRef 317 | fn brain_wallet_address_with_ref( 318 | seed_ref: i64 319 | ) -> crate::Result { 320 | let seed = unsafe { Box::from_raw(seed_ref as *mut String) }; 321 | let address = ethkey_brainwallet_address(&seed); 322 | // so that the reference remains valid 323 | let _ = Box::into_raw(seed) as i64; 324 | Ok(address) 325 | } 326 | 327 | @Java_io_parity_substrateSign_SubstrateSignModule_ethkeySubstrateMiniSecretKey 328 | fn substrate_mini_secret_key( 329 | suri: &str 330 | ) -> crate::Result { 331 | let bytes = sr25519::KeyPair::get_derived_secret(&suri) 332 | .ok_or(crate::Error::KeyPairIsNone)?; 333 | Ok(bytes.to_hex()) 334 | } 335 | 336 | @Java_io_parity_substrateSign_SubstrateSignModule_ethkeySubstrateMiniSecretKeyWithRef 337 | fn substrate_mini_secret_key_with_ref ( 338 | seed_ref: i64, 339 | suri_suffix: &str 340 | ) -> crate::Result { 341 | let seed = unsafe { Box::from_raw(seed_ref as *mut String) }; 342 | let suri = format!("{}{}", &seed, suri_suffix); 343 | let bytes = sr25519::KeyPair::get_derived_secret(&suri) 344 | .ok_or(crate::Error::KeyPairIsNone)?; 345 | let _ = Box::into_raw(seed) as i64; 346 | Ok(bytes.to_hex()) 347 | } 348 | } 349 | 350 | ffi_support::define_string_destructor!(signer_destroy_string); 351 | 352 | #[cfg(test)] 353 | mod tests { 354 | use super::*; 355 | 356 | static SEED_PHRASE: &str = 357 | "grant jaguar wish bench exact find voice habit tank pony state salmon"; 358 | static SURI_SUFFIX: &str = "//hard/soft/0"; 359 | static SURI_SUFFIX_HARD: &str = "//hard"; 360 | static ENCRYPTED_SEED: &str = "{\"cipher\":\"aes-128-ctr\",\"cipherparams\":{\"iv\":\"47b4b75d13045ff7569da858e234f7ea\"},\"ciphertext\":\"ca1cf5387822b70392c4aeec729676f91ab00a795d7593fb7e52ecc333dbc4a1acbedc744b5d8d519c714e194bd741995244c8128bfdce6c184d6bda4ca136ed265eedcee9\",\"kdf\":\"pbkdf2\",\"kdfparams\":{\"c\":10240,\"dklen\":32,\"prf\":\"hmac-sha256\",\"salt\":\"b4a2d1edd1a70fe2eb48d7aff15c19e234f6aa211f5142dddb05a59af12b3381\"},\"mac\":\"b38a54eb382f2aa1a8be2f7b86fe040fe112d0f42fea03fac186dccdd7ae3eb9\"}"; 361 | static PIN: &str = "000000"; 362 | static SUBSTRATE_ADDRESS: &str = "5D4kaJXj5HVoBw2tFFsDj56BjZdPhXKxgGxZuKk4K3bKqHZ6"; 363 | static ETHEREUM_ADDRESS: &str = "bip39:f85f35e47e976650641ecd1a644e33edccc9cab1"; 364 | 365 | #[test] 366 | fn test_random_phrase() { 367 | let result_12 = random_phrase(12); 368 | assert_eq!(12, result_12.split_whitespace().count()); 369 | let result_24 = random_phrase(24); 370 | assert_eq!(24, result_24.split_whitespace().count()); 371 | let result_17 = random_phrase(17); 372 | assert_eq!(24, result_17.split_whitespace().count()); 373 | } 374 | 375 | #[test] 376 | fn test_blake() { 377 | let data = "454545454545454545454545454545454545454545454545454545454545454501\ 378 | 000000000000002481853da20b9f4322f34650fea5f240dcbfb266d02db94bfa01\ 379 | 53c31f4a29dbdbf025dd4a69a6f4ee6e1577b251b655097e298b692cb34c18d318\ 380 | 2cac3de0dc00000000"; 381 | let expected = "1025e5db74fdaf4d2818822dccf0e1604ae9ccc62f26cecfde23448ff0248abf"; 382 | let result = blake(data); 383 | 384 | assert_eq!(expected.to_string(), result.unwrap()); 385 | } 386 | 387 | #[test] 388 | fn test_rlp_item() { 389 | let rlp = "f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804"; 390 | assert_eq!(rlp_item(rlp, 0).unwrap(), "".to_owned()); 391 | assert_eq!(rlp_item(rlp, 1).unwrap(), "01".to_owned()); 392 | assert_eq!(rlp_item(rlp, 2).unwrap(), "5208".to_owned()); 393 | assert_eq!( 394 | rlp_item(rlp, 3).unwrap(), 395 | "095e7baea6a6c7c4c2dfeb977efac326af552d87".to_owned() 396 | ); 397 | assert_eq!(rlp_item(rlp, 4).unwrap(), "0a".to_owned()); 398 | assert_eq!(rlp_item(rlp, 5).unwrap(), "".to_owned()); 399 | } 400 | 401 | #[test] 402 | fn test_substrate_brainwallet_address() { 403 | // Secret seed: 0xb139e4050f80172b44957ef9d1755ef5c96c296d63b8a2b50025bf477bd95224 404 | // Public key (hex): 0x944eeb240615f4a94f673f240a256584ba178e22dd7b67503a753968e2f95761 405 | let expected = "5FRAPSnpgmnXAnmPVv68fT6o7ntTvaZmkTED8jDttnXs9k4n"; 406 | let generated = substrate_brainwallet_address(SEED_PHRASE, 42).unwrap(); 407 | 408 | assert_eq!(expected, generated); 409 | } 410 | 411 | #[test] 412 | fn test_substrate_secret() { 413 | let data_pointer = decrypt_data_ref(ENCRYPTED_SEED, String::from(PIN)).unwrap(); 414 | let suri = format!("{}{}", SEED_PHRASE, SURI_SUFFIX_HARD); 415 | let expected = "0c4a1f0e772497883ba79c484dfed441008c38572769ab40260a959127949665"; 416 | let generated = substrate_mini_secret_key(&suri).unwrap(); 417 | assert_eq!(expected, generated); 418 | let passworded_suri = format!("{}///password", SURI_SUFFIX_HARD); 419 | let generated_passworded_secret= substrate_mini_secret_key_with_ref(data_pointer, &passworded_suri).unwrap(); 420 | let expected_passworded_secret = "057687d479e550b1c0caca121db7e7519c573ebb6a7ce6f771213e41900181f6"; 421 | assert_eq!(expected_passworded_secret, generated_passworded_secret); 422 | } 423 | 424 | #[test] 425 | fn test_substrate_secret_with_ref() { 426 | let data_pointer = decrypt_data_ref(ENCRYPTED_SEED, String::from(PIN)).unwrap(); 427 | let expected = "0c4a1f0e772497883ba79c484dfed441008c38572769ab40260a959127949665"; 428 | let generated = substrate_mini_secret_key_with_ref(data_pointer, SURI_SUFFIX_HARD).unwrap(); 429 | assert_eq!(expected, generated); 430 | } 431 | 432 | #[test] 433 | fn test_substrate_brainwallet_address_suri() { 434 | let suri = format!("{}{}", SEED_PHRASE, SURI_SUFFIX); 435 | let generated = substrate_brainwallet_address(&suri, 42).unwrap(); 436 | 437 | assert_eq!(SUBSTRATE_ADDRESS, generated); 438 | } 439 | 440 | #[test] 441 | fn test_substrate_sign() { 442 | let msg: String = b"Build The Future".to_hex(); 443 | let signature = substrate_brainwallet_sign(SEED_PHRASE, &msg).unwrap(); 444 | 445 | let is_valid = schnorrkel_verify(SEED_PHRASE, &msg, &signature).unwrap(); 446 | 447 | assert!(is_valid); 448 | } 449 | 450 | #[test] 451 | fn test_substrate_sign_with_ref() { 452 | let msg: String = b"Build The Future".to_hex(); 453 | let data_pointer = decrypt_data_ref(ENCRYPTED_SEED, String::from(PIN)).unwrap(); 454 | let signature_by_ref = 455 | substrate_brainwallet_sign_with_ref(data_pointer, SURI_SUFFIX, &msg).unwrap(); 456 | let suri = format!("{}{}", SEED_PHRASE, SURI_SUFFIX); 457 | let is_valid = schnorrkel_verify(&suri, &msg, &signature_by_ref).unwrap(); 458 | destroy_data_ref(data_pointer); 459 | assert!(is_valid); 460 | } 461 | 462 | #[test] 463 | fn decrypt_with_ref() { 464 | let decrypted_result = decrypt_data(ENCRYPTED_SEED, String::from(PIN)).unwrap(); 465 | assert_eq!(SEED_PHRASE, decrypted_result); 466 | } 467 | 468 | #[test] 469 | fn test_generate_substrate_address() { 470 | let data_pointer = decrypt_data_ref(ENCRYPTED_SEED, String::from(PIN)).unwrap(); 471 | let address = substrate_address_with_ref(data_pointer, SURI_SUFFIX, 42).unwrap(); 472 | destroy_data_ref(data_pointer); 473 | assert_eq!(address, SUBSTRATE_ADDRESS); 474 | } 475 | 476 | #[test] 477 | fn test_generate_ethereum_address() { 478 | let data_pointer = decrypt_data_ref(ENCRYPTED_SEED, String::from(PIN)).unwrap(); 479 | let address = brain_wallet_address_with_ref(data_pointer).unwrap(); 480 | destroy_data_ref(data_pointer); 481 | assert_eq!(address, ETHEREUM_ADDRESS); 482 | } 483 | } 484 | -------------------------------------------------------------------------------- /rust/signer/src/result.rs: -------------------------------------------------------------------------------- 1 | use thiserror::Error; 2 | 3 | pub type Result = anyhow::Result; 4 | 5 | #[derive(Error, Debug)] 6 | pub enum Error { 7 | #[error("Could not derive key pair")] 8 | KeyPairIsNone, 9 | #[error("Error converting from hex: {0:?}")] 10 | FromHex(rustc_hex::FromHexError), 11 | #[error("Ethsign error: {0:?}")] 12 | Ethsign(ethsign::Error), 13 | #[error("Signature error: {0:?}")] 14 | Signature(schnorrkel::SignatureError), 15 | #[error("Error creating icon: {0:?}")] 16 | Blockies(blockies::Error), 17 | #[error("Error rendering QR code: {0:?}")] 18 | Pixelate(pixelate::Error), 19 | } 20 | -------------------------------------------------------------------------------- /rust/signer/src/sr25519.rs: -------------------------------------------------------------------------------- 1 | use base58::ToBase58; 2 | use bip39::{Language, Mnemonic}; 3 | use codec::{Decode, Encode}; 4 | use regex::Regex; 5 | use schnorrkel::{ExpansionMode, MiniSecretKey, SecretKey, Signature}; 6 | use schnorrkel::derive::{ChainCode, Derivation}; 7 | use substrate_bip39::mini_secret_from_entropy; 8 | use lazy_static::lazy_static; 9 | 10 | pub struct KeyPair(schnorrkel::Keypair); 11 | 12 | const SIGNING_CTX: &[u8] = b"substrate"; 13 | const JUNCTION_ID_LEN: usize = 32; 14 | const CHAIN_CODE_LENGTH: usize = 32; 15 | const MINI_SECRET_KEY_LENGTH: usize = 32; 16 | 17 | impl KeyPair { 18 | pub fn from_bip39_phrase(phrase: &str, password: Option<&str>) -> Option { 19 | let mnemonic = Mnemonic::from_phrase(phrase, Language::English).ok()?; 20 | let mini_secret_key = 21 | mini_secret_from_entropy(mnemonic.entropy(), password.unwrap_or("")).ok()?; 22 | Some(KeyPair( 23 | mini_secret_key.expand_to_keypair(ExpansionMode::Ed25519), 24 | )) 25 | } 26 | 27 | fn derive_secret_key(&self, path: impl Iterator) -> Option { 28 | let mut result: SecretKey = self.0.secret.clone(); 29 | let mut path_peekable = path.peekable(); 30 | let mut derived_result: Option = None; 31 | while let Some(derive_junction) = path_peekable.next() { 32 | if path_peekable.peek().is_some() { 33 | result = match derive_junction { 34 | DeriveJunction::Soft(cc) => result.derived_key_simple(ChainCode(cc), &[]).0, 35 | DeriveJunction::Hard(cc) => derive_hard_junction(&result, cc), 36 | } 37 | } 38 | let last_chain_code = derive_junction.unwrap_inner(); 39 | let (derived_mini_secret_key, _) = result.hard_derive_mini_secret_key(Some(ChainCode(last_chain_code)), b""); 40 | derived_result = Some(derived_mini_secret_key); 41 | } 42 | 43 | derived_result 44 | } 45 | 46 | pub fn get_derived_secret(suri: &str) -> Option<[u8; MINI_SECRET_KEY_LENGTH]> { 47 | lazy_static! { 48 | static ref RE_SURI: Regex = { 49 | Regex::new(r"^(?P\w+( \w+)*)?(?P(//?[^/]+)*)(///(?P.*))?$") 50 | .expect("constructed from known-good static value; qed") 51 | }; 52 | static ref RE_JUNCTION: Regex = 53 | Regex::new(r"/(/?[^/]+)").expect("constructed from known-good static value; qed"); 54 | } 55 | let cap = RE_SURI.captures(suri)?; 56 | let paths = RE_JUNCTION 57 | .captures_iter(&cap["path"]) 58 | .map(|j| DeriveJunction::from(&j[1])); 59 | let pair = Self::from_bip39_phrase( 60 | cap.name("phrase").map(|p| p.as_str())?, 61 | cap.name("password").map(|p| p.as_str()), 62 | )?; 63 | let mini_secret_key = pair.derive_secret_key(paths)?; 64 | Some(*mini_secret_key.as_bytes()) 65 | } 66 | 67 | // Should match implementation at https://github.com/paritytech/substrate/blob/master/core/primitives/src/crypto.rs#L653-L682 68 | pub fn from_suri(suri: &str) -> Option { 69 | lazy_static! { 70 | static ref RE_SURI: Regex = { 71 | Regex::new(r"^(?P\w+( \w+)*)?(?P(//?[^/]+)*)(///(?P.*))?$") 72 | .expect("constructed from known-good static value; qed") 73 | }; 74 | static ref RE_JUNCTION: Regex = 75 | Regex::new(r"/(/?[^/]+)").expect("constructed from known-good static value; qed"); 76 | } 77 | let cap = RE_SURI.captures(suri)?; 78 | let paths = RE_JUNCTION 79 | .captures_iter(&cap["path"]) 80 | .map(|j| DeriveJunction::from(&j[1])); 81 | let pair = Self::from_bip39_phrase( 82 | cap.name("phrase").map(|p| p.as_str())?, 83 | cap.name("password").map(|p| p.as_str()), 84 | )?; 85 | Some(pair.derive(paths)) 86 | } 87 | 88 | fn derive(&self, path: impl Iterator) -> Self { 89 | let init = self.0.secret.clone(); 90 | let result = path.fold(init, |acc, j| match j { 91 | DeriveJunction::Soft(cc) => acc.derived_key_simple(ChainCode(cc), &[]).0, 92 | DeriveJunction::Hard(cc) => derive_hard_junction(&acc, cc), 93 | }); 94 | 95 | KeyPair(result.to_keypair()) 96 | } 97 | 98 | pub fn ss58_address(&self, prefix: u8) -> String { 99 | let mut v = vec![prefix]; 100 | v.extend_from_slice(&self.0.public.to_bytes()); 101 | let r = ss58hash(&v); 102 | v.extend_from_slice(&r.as_bytes()[0..2]); 103 | v.to_base58() 104 | } 105 | 106 | pub fn sign(&self, message: &[u8]) -> [u8; 64] { 107 | let context = schnorrkel::signing_context(SIGNING_CTX); 108 | self.0.sign(context.bytes(message)).to_bytes() 109 | } 110 | 111 | pub fn verify_signature( 112 | &self, 113 | message: &[u8], 114 | signature: &[u8], 115 | ) -> crate::result::Result { 116 | let context = schnorrkel::signing_context(SIGNING_CTX); 117 | let signature = 118 | Signature::from_bytes(signature).map_err(|e| crate::result::Error::Signature(e))?; 119 | Ok(self.0.verify(context.bytes(&message), &signature).is_ok()) 120 | } 121 | } 122 | 123 | fn derive_hard_junction(secret: &SecretKey, cc: [u8; CHAIN_CODE_LENGTH]) -> SecretKey { 124 | secret 125 | .hard_derive_mini_secret_key(Some(ChainCode(cc)), b"") 126 | .0 127 | .expand(ExpansionMode::Ed25519) 128 | } 129 | 130 | /// A since derivation junction description. It is the single parameter used when creating 131 | /// a new secret key from an existing secret key and, in the case of `SoftRaw` and `SoftIndex` 132 | /// a new public key from an existing public key. 133 | #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Encode, Decode)] 134 | enum DeriveJunction { 135 | /// Soft (vanilla) derivation. Public keys have a correspondent derivation. 136 | Soft([u8; JUNCTION_ID_LEN]), 137 | /// Hard ("hardened") derivation. Public keys do not have a correspondent derivation. 138 | Hard([u8; JUNCTION_ID_LEN]), 139 | } 140 | 141 | impl DeriveJunction { 142 | /// Consume self to return a hard derive junction with the same chain code. 143 | fn harden(self) -> Self { 144 | DeriveJunction::Hard(self.unwrap_inner()) 145 | } 146 | 147 | /// Create a new soft (vanilla) DeriveJunction from a given, encodable, value. 148 | /// 149 | /// If you need a hard junction, use `hard()`. 150 | fn soft(index: T) -> Self { 151 | let mut cc: [u8; JUNCTION_ID_LEN] = Default::default(); 152 | index.using_encoded(|data| { 153 | if data.len() > JUNCTION_ID_LEN { 154 | let hash_result = blake2_rfc::blake2b::blake2b(JUNCTION_ID_LEN, &[], data); 155 | let hash = hash_result.as_bytes(); 156 | cc.copy_from_slice(hash); 157 | } else { 158 | cc[0..data.len()].copy_from_slice(data); 159 | } 160 | }); 161 | DeriveJunction::Soft(cc) 162 | } 163 | 164 | /// Consume self to return the chain code. 165 | fn unwrap_inner(self) -> [u8; JUNCTION_ID_LEN] { 166 | match self { 167 | DeriveJunction::Hard(c) | DeriveJunction::Soft(c) => c, 168 | } 169 | } 170 | } 171 | 172 | impl> From for DeriveJunction { 173 | fn from(j: T) -> DeriveJunction { 174 | let j = j.as_ref(); 175 | let (code, hard) = if j.starts_with("/") { 176 | (&j[1..], true) 177 | } else { 178 | (j, false) 179 | }; 180 | 181 | let res = if let Ok(n) = str::parse::(code) { 182 | // number 183 | DeriveJunction::soft(n) 184 | } else { 185 | // something else 186 | DeriveJunction::soft(code) 187 | }; 188 | 189 | if hard { 190 | res.harden() 191 | } else { 192 | res 193 | } 194 | } 195 | } 196 | 197 | fn ss58hash(data: &[u8]) -> blake2_rfc::blake2b::Blake2bResult { 198 | const PREFIX: &[u8] = b"SS58PRE"; 199 | 200 | let mut context = blake2_rfc::blake2b::Blake2b::new(64); 201 | context.update(PREFIX); 202 | context.update(data); 203 | context.finalize() 204 | } 205 | -------------------------------------------------------------------------------- /scripts/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source ./scripts/variables.sh 4 | 5 | # Build iOS 6 | cd ./rust/signer 7 | 8 | # Build android 9 | 10 | if [ -z ${NDK_HOME+x} ]; 11 | then 12 | printf 'Please install android-ndk\n\n' 13 | printf 'from https://developer.android.com/ndk/downloads or with sdkmanager' 14 | exit 1 15 | else 16 | printf "Building Andriod targets..."; 17 | fi 18 | 19 | printf "Building ARM64 Andriod targets..."; 20 | CC_aarch64_linux_android="${ANDROID_PREBUILD_BIN}/aarch64-linux-android${API_LEVEL}-clang" \ 21 | CXX_aarch64_linux_android="${ANDROID_PREBUILD_BIN}/aarch64-linux-android${API_LEVEL}-clang++" \ 22 | CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER="${ANDROID_PREBUILD_BIN}/aarch64-linux-android${API_LEVEL}-clang" \ 23 | AR_aarch64_linux_android="${ANDROID_PREBUILD_BIN}/aarch64-linux-android-ar" \ 24 | cargo build --target aarch64-linux-android --release 25 | 26 | printf "Building ARMv7 Andriod targets..."; 27 | CC_armv7_linux_androideabi="${ANDROID_PREBUILD_BIN}/armv7a-linux-androideabi${API_LEVEL}-clang" \ 28 | CXX_armv7_linux_androideabi="${ANDROID_PREBUILD_BIN}/armv7a-linux-androideabi${API_LEVEL}-clang++" \ 29 | CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER="${ANDROID_PREBUILD_BIN}/armv7a-linux-androideabi${API_LEVEL}-clang" \ 30 | AR_armv7_linux_androideabi="${ANDROID_PREBUILD_BIN}/arm-linux-androideabi-ar" \ 31 | cargo build --target armv7-linux-androideabi --release 32 | 33 | printf "Building 32-bit x86 Andriod targets..."; 34 | CC_i686_linux_android="${ANDROID_PREBUILD_BIN}/i686-linux-android${API_LEVEL}-clang" \ 35 | CXX_i686_linux_android="${ANDROID_PREBUILD_BIN}/i686-linux-android${API_LEVEL}-clang++" \ 36 | CARGO_TARGET_I686_LINUX_ANDROID_LINKER="${ANDROID_PREBUILD_BIN}/i686-linux-android${API_LEVEL}-clang" \ 37 | AR_i686_linux_android="${ANDROID_PREBUILD_BIN}/i686-linux-android-ar" \ 38 | cargo build --target i686-linux-android --release 39 | 40 | printf "Building 64-bit x86 Andriod targets..."; 41 | CC_x86_64_linux_android="${ANDROID_PREBUILD_BIN}/x86_64-linux-android${API_LEVEL}-clang" \ 42 | CXX_x86_64_linux_android="${ANDROID_PREBUILD_BIN}/x86_64-linux-android${API_LEVEL}-clang++" \ 43 | CARGO_TARGET_X86_64_LINUX_ANDROID_LINKER="${ANDROID_PREBUILD_BIN}/x86_64-linux-android${API_LEVEL}-clang" \ 44 | AR_x86_64_linux_android="${ANDROID_PREBUILD_BIN}/x86_64-linux-android-ar" \ 45 | cargo build --target x86_64-linux-android --release 46 | 47 | for i in "${!ANDROID_ARCHS[@]}"; 48 | do 49 | mkdir -p -v "../../android/src/main/jniLibs/${ANDROID_FOLDER[$i]}" 50 | cp "./target/${ANDROID_ARCHS[$i]}/release/lib${LIB_NAME}.so" "../../android/src/main/jniLibs/${ANDROID_FOLDER[$i]}/lib${LIB_NAME}.so" 51 | done 52 | 53 | printf "Building iOS targets..."; 54 | 55 | for i in "${IOS_ARCHS[@]}"; 56 | do 57 | rustup target add "$i"; 58 | cargo build --target "$i" --release --no-default-features 59 | done 60 | 61 | lipo -create -output "../../ios/lib${LIB_NAME}.a" target/x86_64-apple-ios/release/libsigner.a target/armv7-apple-ios/release/libsigner.a target/armv7s-apple-ios/release/libsigner.a target/aarch64-apple-ios/release/libsigner.a 62 | 63 | 64 | #echo "hello tom" > read.txt 65 | #cat read.txt 66 | -------------------------------------------------------------------------------- /scripts/init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source ./scripts/variables.sh 4 | 5 | cargo install cargo-lipo 6 | 7 | case "$(uname | tr '[:upper:]' '[:lower:]')" in 8 | darwin) 9 | echo 'Add rust toolchains for android and ios' 10 | for i in "${IOS_ARCHS[@]}"; 11 | do rustup target add "$i"; 12 | done 13 | for i in "${ANDROID_ARCHS[@]}"; 14 | do rustup target add "$i" ; 15 | done 16 | ;; 17 | linux) 18 | echo 'Add rust toolchains for android' 19 | for i in "${ANDROID_ARCHS[@]}"; 20 | do rustup target add "$i" ; 21 | done 22 | ;; 23 | *) 24 | echo 'Please use a Linux or Mac to build' 25 | ;; 26 | esac 27 | -------------------------------------------------------------------------------- /scripts/variables.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Change this name to the rust library name 4 | LIB_NAME=signer 5 | API_LEVEL=29 6 | 7 | ANDROID_ARCHS=(aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android) 8 | ANDROID_FOLDER=(arm64-v8a armeabi-v7a x86 x86_64) 9 | ANDROID_BIN_PREFIX=(aarch64-linux-android armv7a-linux-androideabi i686-linux-android x86_64-linux-android) 10 | IOS_ARCHS=(aarch64-apple-ios x86_64-apple-ios armv7-apple-ios armv7s-apple-ios) 11 | OS_ARCH=$(uname | tr '[:upper:]' '[:lower:]') 12 | 13 | ANDROID_PREBUILD_BIN=${NDK_HOME}/toolchains/llvm/prebuilt/${OS_ARCH}-x86_64/bin 14 | 15 | #CC_aarch64_linux_android=${ANDROID_PREBUILD_BIN}/aarch64-linux-android29-clang 16 | #CC_armv7_linux_androideabi=${ANDROID_PREBUILD_BIN}/armv7a-linux-androideabi29-clang 17 | #CC_i686_linux_android=${ANDROID_PREBUILD_BIN}/i686-linux-android29-clang 18 | #CC_x86_64_linux_android=${ANDROID_PREBUILD_BIN}/x86_64-linux-android29-clang 19 | --------------------------------------------------------------------------------