Unverified Commit af4eacd4 authored by Hanwen Cheng's avatar Hanwen Cheng Committed by GitHub
Browse files

refactor: extract rust packages into independent library (#650)

* remove rust related files

* use npm libraries

* Update native.ts

* remove redundant files

* use npm package

* fix android building

* fix unit test

* Update actions.yml
parent 90f8fbb8
Pipeline #99235 failed with stages
in 3 minutes and 9 seconds
name: E2E & Rust Unit
name: E2E Test
on:
pull_request:
......@@ -18,40 +18,6 @@ jobs:
- name: Checkout submodules
shell: bash
run: git submodule update --init --recursive
- name: Install 1.41.1 toolchain
uses: actions-rs/toolchain@v1.0.5
with:
toolchain: 1.41.1
profile: minimal
override: true
- name: Add target x86_64-apple-ios
uses: actions-rs/toolchain@v1.0.5
with:
toolchain: 1.41.1
target: x86_64-apple-ios
- name: Cache cargo registry
uses: actions/cache@v1.1.2
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo index
uses: actions/cache@v1.1.2
with:
path: ~/.cargo/git
key: ${{ runner.os }}-cargo-git-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo build
uses: actions/cache@v1.1.2
with:
path: target
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}
- name: Cache sccache MacOS
uses: actions/cache@v1.1.2
with:
path: "/Users/runner/Library/Caches/Mozilla.sccache"
key: ${{ runner.os }}-sccache-build-tests-${{ hashFiles('**/Cargo.lock') }}
- name: Install sccache for MacOS
shell: pwsh
run: pwsh scripts/actions/install-sccache.ps1 ${{ runner.os}}
- name: Install NodeJS
uses: actions/setup-node@v1
with:
......@@ -92,16 +58,6 @@ jobs:
yarn
- name: Build CocoaPods
run: cd ios && pod install && cd ..
- name: Build targets
run: |
cd rust/signer
cargo build --target x86_64-apple-ios --release --no-default-features
lipo -create -output libsigner.a ./target/x86_64-apple-ios/release/libsigner.a
- name: Rust Unit Test
run: yarn test-rust
- name: Stop sccache
if: always()
run: sccache --stop-server
- name: Detox biuld
run: yarn build-e2e:ci
- name: Detox test
......
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
package io.parity.signer;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Promise;
/**
* Created by marek on 20/02/2017.
*/
public class EthkeyBridge extends ReactContextBaseJavaModule {
static {
System.loadLibrary("signer");
}
private void rejectWithException(Promise promise, String code, Exception e) {
String[] sp = e.getMessage().split(": ");
String s = sp[sp.length - 1].trim().replace("\"", "");
promise.reject(code, s);
}
@Override
public String getName() {
return "EthkeyBridge";
}
public EthkeyBridge(ReactApplicationContext reactContext) {
super(reactContext);
}
@ReactMethod
public void brainWalletAddress(String seed, Promise promise) {
promise.resolve(ethkeyBrainwalletAddress(seed));
}
@ReactMethod
public void brainWalletBIP39Address(String seed, Promise promise) {
try {
promise.resolve(ethkeyBrainwalletBIP39Address(seed));
} catch (Exception e) {
rejectWithException(promise, "brainwallet bip39 address", e);
}
}
@ReactMethod
public void brainWalletSign(String seed, String message, Promise promise) {
try {
promise.resolve(ethkeyBrainwalletSign(seed, message));
} catch (Exception e) {
rejectWithException(promise, "brainwallet sign", e);
}
}
@ReactMethod
public void rlpItem(String rlp, int position, Promise promise) {
try {
promise.resolve(ethkeyRlpItem(rlp, position));
} catch (Exception e) {
rejectWithException(promise, "rlp item", e);
}
}
@ReactMethod
public void keccak(String data, Promise promise) {
try {
promise.resolve(ethkeyKeccak(data));
} catch (Exception e) {
rejectWithException(promise, "keccak", e);
}
}
@ReactMethod
public void blake2b(String data, Promise promise) {
try {
promise.resolve(ethkeyBlake(data));
} catch (Exception e) {
rejectWithException(promise, "blake2b", e);
}
}
@ReactMethod
public void ethSign(String data, Promise promise) {
promise.resolve(ethkeyEthSign(data));
}
@ReactMethod
public void blockiesIcon(String seed, Promise promise) {
promise.resolve(ethkeyBlockiesIcon(seed));
}
@ReactMethod
public void randomPhrase(int wordsNumber, Promise promise) {
promise.resolve(ethkeyRandomPhrase(wordsNumber));
}
@ReactMethod
public void encryptData(String data, String password, Promise promise) {
promise.resolve(ethkeyEncryptData(data, password));
}
@ReactMethod
public void decryptData(String data, String password, Promise promise) {
try {
promise.resolve(ethkeyDecryptData(data, password));
} catch (Exception e) {
rejectWithException(promise, "decrypt data", e);
}
}
@ReactMethod
public void qrCode(String data, Promise promise) {
try {
promise.resolve(ethkeyQrCode(data));
} catch (Exception e) {
rejectWithException(promise, "qr code", e);
}
}
@ReactMethod
public void qrCodeHex(String data, Promise promise) {
try {
promise.resolve(ethkeyQrCodeHex(data));
} catch (Exception e) {
rejectWithException(promise, "qr code hex", e);
}
}
@ReactMethod
public void substrateAddress(String seed, int prefix, Promise promise) {
try {
promise.resolve(substrateBrainwalletAddress(seed, prefix));
} catch (Exception e) {
rejectWithException(promise, "substrate address", e);
}
}
@ReactMethod
public void substrateSign(String seed, String message, Promise promise) {
try {
promise.resolve(substrateBrainwalletSign(seed, message));
} catch (Exception e) {
rejectWithException(promise, "substrate sign", e);
}
}
@ReactMethod
public void schnorrkelVerify(String seed, String message, String signature, Promise promise) {
try {
promise.resolve(schnorrkelVerify(seed, message, signature));
} catch (Exception e) {
rejectWithException(promise, "schnorrkel verify", e);
}
}
@ReactMethod
public void decryptDataRef(String data, String password, Promise promise) {
try {
// `long` is incompatible with the bridge so pass as a double
double d = Double.longBitsToDouble(ethkeyDecryptDataRef(data, password));
if (Double.isNaN(d)) {
promise.reject("reference is nan", "reference is nan");
} else {
promise.resolve(d);
}
} catch (Exception e) {
rejectWithException(promise, "decrypt data ref", e);
}
}
@ReactMethod
public void destroyDataRef(double data_ref, Promise promise) {
try {
ethkeyDestroyDataRef(Double.doubleToRawLongBits(data_ref));
promise.resolve(0);
} catch (Exception e) {
rejectWithException(promise, "destroy data ref", e);
}
}
@ReactMethod
public void brainWalletSignWithRef(double seed_ref, String message, Promise promise) {
try {
promise.resolve(ethkeyBrainwalletSignWithRef(Double.doubleToRawLongBits(seed_ref), message));
} catch (Exception e) {
rejectWithException(promise, "brainwallet sign with ref", e);
}
}
@ReactMethod
public void substrateSignWithRef(double seed_ref, String suriSuffix, String message, Promise promise) {
try {
String s = ethkeySubstrateBrainwalletSignWithRef(Double.doubleToRawLongBits(seed_ref), suriSuffix, message);
promise.resolve(s);
} catch (Exception e) {
rejectWithException(promise, "substrate sign with ref", e);
}
}
@ReactMethod
public void brainWalletAddressWithRef(double seedRef, Promise promise) {
try {
String s = ethkeyBrainWalletAddressWithRef(Double.doubleToRawLongBits(seedRef));
promise.resolve(s);
} catch (Exception e) {
rejectWithException(promise, "brainwallet address with ref", e);
}
}
@ReactMethod
public void substrateAddressWithRef(double seedRef, String suriSuffix, int prefix, Promise promise) {
try {
String substrateAddress = ethkeySubstrateWalletAddressWithRef(Double.doubleToRawLongBits(seedRef), suriSuffix, prefix);
promise.resolve(substrateAddress);
} catch (Exception e) {
rejectWithException(promise, "substrate address with ref", e);
}
}
@ReactMethod
public void substrateSecretWithRef(double seedRef, String suriSuffix, Promise promise) {
try {
String derivedSubstrateSecret = ethkeySubstrateMiniSecretKeyWithRef(Double.doubleToRawLongBits(seedRef), suriSuffix);
promise.resolve(derivedSubstrateSecret);
} catch (Exception e) {
rejectWithException(promise, "substrate secret", e);
}
}
@ReactMethod
public void substrateSecret(String suri, Promise promise) {
try {
String derivedSubstrateSecret = ethkeySubstrateMiniSecretKey(suri);
promise.resolve(derivedSubstrateSecret);
} catch (Exception e) {
rejectWithException(promise, "substrate secret with ref", e);
}
}
private static native String ethkeyBrainwalletAddress(String seed);
private static native String ethkeyBrainwalletBIP39Address(String seed);
private static native String ethkeyBrainwalletSign(String seed, String message);
private static native String ethkeyRlpItem(String data, int position);
private static native String ethkeyKeccak(String data);
private static native String ethkeyBlake(String data);
private static native String ethkeyEthSign(String data);
private static native String ethkeyBlockiesIcon(String seed);
private static native String ethkeyRandomPhrase(int wordsNumber);
private static native String ethkeyEncryptData(String data, String password);
private static native String ethkeyDecryptData(String data, String password);
private static native String ethkeyQrCode(String data);
private static native String ethkeyQrCodeHex(String data);
private static native String substrateBrainwalletAddress(String seed, int prefix);
private static native String substrateBrainwalletSign(String seed, String message);
private static native boolean schnorrkelVerify(String seed, String message, String signature);
private static native long ethkeyDecryptDataRef(String data, String password);
private static native void ethkeyDestroyDataRef(long data_ref);
private static native String ethkeyBrainwalletSignWithRef(long seed_ref, String message);
private static native String ethkeySubstrateBrainwalletSignWithRef(long seed_ref, String suriSuffix, String message);
private static native String ethkeySubstrateWalletAddressWithRef(long seedRef, String suriSuffix, int prefix);
private static native String ethkeyBrainWalletAddressWithRef(long seedRef);
private static native String ethkeySubstrateMiniSecretKey(String suri);
private static native String ethkeySubstrateMiniSecretKeyWithRef(long seedRef, String suriSuffix);
}
......@@ -26,7 +26,7 @@ public class MainApplication extends Application implements ReactApplication {
@SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackageList(this).getPackages();
// Packages that cannot be autolinked yet can be added manually here, for example:
packages.add(new EthkeyBridgePackage());
// packages.add(new EthkeyBridgePackage());
return packages;
}
......
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libsigner
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libsigner.so
include $(PREBUILT_SHARED_LIBRARY)
\ No newline at end of file
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// Copyright 2015-2020 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
......@@ -14,35 +14,4 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
package io.parity.signer;
import java.util.Collections;
import java.util.List;
import java.util.ArrayList;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
/**
* Created by marek on 20/02/2017.
*/
public class EthkeyBridgePackage implements ReactPackage {
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new EthkeyBridge(reactContext));
return modules;
}
}
import Foundation
This diff is collapsed.
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//
// EthkeyBridge.m
// NativeSigner
//
// Created by Marek Kotewicz on 19/02/2017.
//
#import <React/RCTBridgeModule.h>
@interface RCT_EXTERN_MODULE(EthkeyBridge, NSObject)
// explanation about threading here: https://stackoverflow.com/a/50775641/3060739
- (dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
}
+ (BOOL)requiresMainQueueSetup
{
return YES;
}
RCT_EXTERN_METHOD(brainWalletAddress:(NSString*)seed resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(brainWalletSecret:(NSString*)seed resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(brainWalletSign:(NSString*)seed message:(NSString*)message resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(rlpItem:(NSString*)rlp position:(NSUInteger)position resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(keccak:(NSString*)data resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(ethSign:(NSString*)data resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(blockiesIcon:(NSString*)seed resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(randomPhrase:(NSInteger*)wordsNumber resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(encryptData:(NSString*)data password:(NSString*)password resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(decryptData:(NSString*)data password:(NSString*)password resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(qrCode:(NSString*)data resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(qrCodeHex:(NSString*)data resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(substrateAddress:(NSString*)seed prefix:(NSUInteger*)prefix resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(substrateSign:(NSString*)seed message:(NSString*)message resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(blake2b:(NSString*)data resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(schnorrkelVerify: (NSString*)seed message:(NSString*)message signature:(NSString*)signature resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(decryptDataRef:(NSString*)data password:(NSString*)password resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(destroyDataRef:(int64_t)dataRef resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(brainWalletSignWithRef:(int64_t)seedRef message:(NSString*)message resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(substrateSignWithRef:(int64_t)seedRef suri_suffix:(NSString*)suri_suffix message:(NSString*)message resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(substrateAddressWithRef:(int64_t)seedRef suri_suffix:(NSString*)suri_suffix prefix:(NSUInteger*)prefix resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(brainWalletAddressWithRef:(int64_t)seedRef resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(substrateSecret:(NSString*)suri resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(substrateSecretWithRef:(int64_t*)seedRef suri_suffix:(NSString*)suri_suffix resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
@end
//
// EthkeyBridge.swift
// NativeSigner
//
// Created by Marek Kotewicz on 19/02/2017.
// Copyright © 2019 Facebook. All rights reserved.
//
import Foundation
func handle_error<T, U>(
resolve: RCTPromiseResolveBlock,
reject: RCTPromiseRejectBlock,
get_result: (UnsafeMutablePointer<ExternError>) -> T,
success: (T) -> U
) -> Void {
var err = ExternError()
let err_ptr: UnsafeMutablePointer<ExternError> = UnsafeMutablePointer(&err)
let res = get_result(err_ptr)
if err_ptr.pointee.code == 0 {
resolve(success(res))
} else {
let val = String(cString: err_ptr.pointee.message)
signer_destroy_string(err_ptr.pointee.message)
reject(String(describing: err_ptr.pointee.code), val, nil)
}
}
@objc(EthkeyBridge)
class EthkeyBridge: NSObject {
public static func requiresMainQueueSetup() -> Bool {
return true;
}
@objc func brainWalletAddress(_ seed: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void {
handle_error(
resolve: resolve,
reject: reject,
get_result: { ethkey_brainwallet_address($0, seed) },
success: { (res: Optional<UnsafePointer<CChar>>) -> String in
let val = String(cString: res!)
signer_destroy_string(res!)
return val
})
}
@objc func brainWalletSign(_ seed: String, message: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void {
handle_error(
resolve: resolve,
reject: reject,
get_result: { ethkey_brainwallet_sign($0, seed, message) },
success: { (res: Optional<UnsafePointer<CChar>>) -> String in
let val = String(cString: res!)
signer_destroy_string(res!)
return val
})
}
@objc func rlpItem(_ rlp: String, position: UInt32, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void {
handle_error(
resolve: resolve,
reject: reject,
get_result: { rlp_item($0, rlp, position) },
success: { (res: Optional<UnsafePointer<CChar>>) -> String in
let val = String(cString: res!)
signer_destroy_string(res!)
return val
})
}
@objc func keccak(_ data: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void {
handle_error(
resolve: resolve,
reject: reject,
get_result: { keccak256($0, data) },
success: { (res: Optional<UnsafePointer<CChar>>) -> String in
let val = String(cString: res!)
signer_destroy_string(res!)
return val
})
}
@objc func blake2b(_ data: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void {
handle_error(
resolve: resolve,
reject: reject,
get_result: { blake($0, data) },
success: { (res: Optional<UnsafePointer<CChar>>) -> String in
let val = String(cString: res!)
signer_destroy_string(res!)
return val
})
}
@objc func ethSign(_ data: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void {
handle_error(
resolve: resolve,
reject: reject,
get_result: { eth_sign($0, data) },
success: { (res: Optional<UnsafePointer<CChar>>) -> String in
let val = String(cString: res!)
signer_destroy_string(res!)
return val
})