Skip to content

Commit

Permalink
New Tor implementation and persistent LND + Tor services
Browse files Browse the repository at this point in the history
  • Loading branch information
kaloudis committed Dec 12, 2023
1 parent fe636dc commit ef20c6b
Show file tree
Hide file tree
Showing 32 changed files with 722 additions and 90 deletions.
10 changes: 10 additions & 0 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,16 @@ dependencies {
// LN address notifications
// Import the Firebase BoM
implementation platform('com.google.firebase:firebase-bom:32.3.1')

// Tor + Persistent LND
implementation "com.jakewharton:process-phoenix:2.0.0"

implementation 'info.guardianproject:tor-android:0.4.7.8'
implementation 'info.guardianproject:jtorctl:0.4.5.7'

implementation('dev.doubledot.doki:library:0.0.1@aar') {
transitive = true
}
}

configurations {
Expand Down
2 changes: 2 additions & 0 deletions android/app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,5 @@
-keep enum com.sifir.** { *;}
-keep public class com.horcrux.svg.** {*;}
-keep class com.swmansion.reanimated.** { *; }

-keep class org.torproject.jni.** { *; }
1 change: 1 addition & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package com.msopentech.thali.android.installer;/*
Copyright (c) Microsoft Open Technologies, Inc.
All Rights Reserved
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache 2 License for the specific language governing permissions and limitations under the License.
*/
//package com.msopentech.thali.android.installer;


import android.content.Context;
import android.util.Log;
//import com.msopentech.thali.toronionproxy.TorInstaller;
//import org.torproject.android.binary.TorResourceInstaller;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
* Installs Tor for an Android app. This is a wrapper around the <code>TorResourceInstaller</code>.
*
* Since this class only deals with installing Tor, it is up to the developer to implement
* the <code>openBridgesStream</code> which will give the bridges for pluggable transports. A
* typical implementation looks like:
*
* <code>
* public InputStream openBridgesStream() throws IOException {
* return context.getResources().openRawResource(R.raw.bridges);
* }
* </code>
*/
public class AndroidTorInstaller {

// private final TorResourceInstaller resourceInstaller;

private static final String TAG = "AndroidTorInstaller";

protected final Context context;

protected File torrcFile;

/**
* The configDir will be the location of tor configuration files. It contains the files, geoip, geoip6,
* bridges.txt and the default torrc file.
*
* The location of tor executable will be in the Android native library directory for the app.
*/
public AndroidTorInstaller(Context context, File configDir) {
// this.resourceInstaller = new TorResourceInstaller(context, configDir);
this.context = context;
}

public void updateTorConfigCustom(String content) throws IOException, TimeoutException {
if(torrcFile == null) {
throw new FileNotFoundException("Unable to find torrc file. Have you installed Tor resources?");
}
// resourceInstaller.updateTorConfigCustom(torrcFile, content);
}

// @Override
public void setup() throws IOException {
// try {
// File torFile = resourceInstaller.installResources();
// if(torFile != null) {
// Log.d("AndroidTorInstaller", "tor executable = " + torFile.getAbsolutePath());
// } else {
// Log.w(TAG, "Failed to setup tor. No tor executable installed");
// throw new IOException("Failed to Failed to setup tor. No tor executable installed");
// }

// this.torrcFile = resourceInstaller.getTorrcFile();
// if(torrcFile != null) {
// Log.d("AndroidTorInstaller", "torrc = " + torrcFile.getAbsolutePath());
// } else {
// Log.w(TAG, "Failed to setup tor. No torrc file installed");
// throw new IOException("Failed to Failed to setup tor. No torrc file installed");
// }

// } catch (TimeoutException e) {
// Log.w(TAG, "Failed to setup tor: " + e.getMessage());
// throw new IOException(e);
// }
}
}
38 changes: 31 additions & 7 deletions android/app/src/main/java/com/zeus/LndMobile.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableType;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.modules.permissions.PermissionsModule;

import com.jakewharton.processphoenix.ProcessPhoenix;
import com.oblador.keychain.KeychainModule;
import com.reactnativecommunity.asyncstorage.ReactDatabaseSupplier;
import com.reactnativecommunity.asyncstorage.AsyncLocalStorageUtil;
import org.torproject.jni.TorService;

// TODO break this class up
class LndMobile extends ReactContextBaseJavaModule {
Expand Down Expand Up @@ -225,6 +225,17 @@ public void onServiceDisconnected(ComponentName className) {

private LndMobileServiceConnection lndMobileServiceConnection;

private boolean getPersistentServicesEnabled(Context context) {
ReactDatabaseSupplier dbSupplier = ReactDatabaseSupplier.getInstance(context);
SQLiteDatabase db = dbSupplier.get();
String persistentServicesEnabled = AsyncLocalStorageUtil.getItemImpl(db, "persistentServicesEnabled");
if (persistentServicesEnabled != null) {
return persistentServicesEnabled.equals("true");
}
// HyperlogLog.w(TAG, "Could not find persistentServicesEnabled in asyncStorage");
return false;
}

public LndMobile(ReactApplicationContext reactContext) {
super(reactContext);
}
Expand Down Expand Up @@ -267,9 +278,13 @@ public void initialize(Promise promise) {

lndMobileServiceConnection = new LndMobileServiceConnection(req);
messenger = new Messenger(new IncomingHandler()); // me

Intent intent = new Intent(getReactApplicationContext(), LndMobileService.class);
if (getPersistentServicesEnabled(getReactApplicationContext())) {
getReactApplicationContext().startForegroundService(intent);
}
// else rely on bindService to start LND
getReactApplicationContext().bindService(
new Intent(getReactApplicationContext(), LndMobileService.class),
intent,
lndMobileServiceConnection,
Context.BIND_AUTO_CREATE
);
Expand Down Expand Up @@ -321,7 +336,7 @@ public void checkStatus(Promise promise) {
}

@ReactMethod
public void startLnd(String args, Promise promise) {
public void startLnd(String args, Boolean isTorEnabled, Boolean isTestnet, Promise promise) {
// TODO args is only used on iOS right now
int req = new Random().nextInt();
requests.put(req, promise);
Expand All @@ -332,7 +347,16 @@ public void startLnd(String args, Promise promise) {
Bundle bundle = new Bundle();

String params = "--lnddir=" + getReactApplicationContext().getFilesDir().getPath();
params += " --nolisten";
if (isTorEnabled) {
int listenPort = ZeusTorUtils.getListenPort(isTestnet);
String controlSocket = "unix://" + getReactApplicationContext().getDir(TorService.class.getSimpleName(), Context.MODE_PRIVATE).getAbsolutePath() + "/data/ControlSocket";
params += " --tor.active --tor.control=" + controlSocket;
params += " --tor.v3 --listen=localhost:" + listenPort;
} else {
// If Tor isn't active, make sure we aren't
// listening at all
params += " --nolisten";
}
bundle.putString(
"args",
params + " " + args
Expand Down
13 changes: 0 additions & 13 deletions android/app/src/main/java/com/zeus/LndMobileScheduledSync.java
Original file line number Diff line number Diff line change
@@ -1,32 +1,19 @@
package app.zeusln.zeus;

import android.util.Log;
import android.content.ComponentName;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteStatement;

import androidx.work.Constraints;
import androidx.work.ExistingPeriodicWorkPolicy;
import androidx.work.PeriodicWorkRequest;
import androidx.work.NetworkType;
import androidx.work.WorkInfo;
import androidx.work.WorkManager;
import androidx.lifecycle.Observer;
import androidx.annotation.Nullable;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Promise;

import com.google.common.util.concurrent.ListenableFuture;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

class LndMobileScheduledSync extends ReactContextBaseJavaModule {
Expand Down

0 comments on commit ef20c6b

Please sign in to comment.