Skip to content

Commit b60e7f2

Browse files
committed
1st commit
0 parents  commit b60e7f2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1723
-0
lines changed

.gitignore

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
*.iml
2+
.gradle
3+
/local.properties
4+
/.idea
5+
/gradle
6+
.DS_Store
7+
/build
8+
/captures
9+
.externalNativeBuild
10+
.cxx

README.md

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# ALCore
2+
3+
4+
Android [c-lightning](https://github.com/ElementsProject/lightning) wallet based on [clightning_ndk](https://github.com/lvaccaro/clightning_ndk).
5+
6+
>> This is a experimenting lightning wallet for testnet. It is only for development purpose, don't use on mainnet.
7+
8+
#### References:
9+
10+
- [ABCore](https://github.com/greenaddress/abcore) Android Bitcoin Core wallet
11+
- [bitcoin_ndk](https://github.com/greenaddress/bitcoin_ndk) ndk build of bitcoin core and knots
12+
- [clightning_ndk](https://github.com/lvaccaro/clightning_ndk) android cross-compilation of c-lightning for Android >= 24 Api
13+
- [c-lightning](https://github.com/ElementsProject/lightning) a Lightning Network implementation in C

app/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/build

app/build.gradle

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
apply plugin: 'com.android.application'
2+
apply plugin: 'kotlin-android'
3+
apply plugin: 'kotlin-android-extensions'
4+
5+
android {
6+
compileSdkVersion 29
7+
buildToolsVersion "29.0.2"
8+
defaultConfig {
9+
applicationId "com.lvaccaro.alcore"
10+
minSdkVersion 19
11+
targetSdkVersion 29
12+
versionCode 1
13+
versionName "1.0"
14+
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
15+
}
16+
buildTypes {
17+
release {
18+
minifyEnabled false
19+
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
20+
}
21+
}
22+
}
23+
24+
dependencies {
25+
implementation fileTree(dir: 'libs', include: ['*.jar'])
26+
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
27+
implementation 'androidx.appcompat:appcompat:1.1.0'
28+
implementation 'androidx.core:core-ktx:1.0.2'
29+
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
30+
implementation 'androidx.preference:preference:1.1.0-alpha05'
31+
implementation 'org.tukaani:xz:1.8'
32+
implementation 'org.apache.commons:commons-compress:1.19'
33+
implementation 'com.google.zxing:core:3.4.0'
34+
implementation 'com.google.android.material:material:1.0.0'
35+
implementation "org.jetbrains.anko:anko-commons:0.10.4"
36+
testImplementation 'junit:junit:4.12'
37+
androidTestImplementation 'androidx.test:runner:1.2.0'
38+
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
39+
}

app/proguard-rules.pro

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Add project specific ProGuard rules here.
2+
# You can control the set of applied configuration files using the
3+
# proguardFiles setting in build.gradle.
4+
#
5+
# For more details, see
6+
# http://developer.android.com/guide/developing/tools/proguard.html
7+
8+
# If your project uses WebView with JS, uncomment the following
9+
# and specify the fully qualified class name to the JavaScript interface
10+
# class:
11+
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12+
# public *;
13+
#}
14+
15+
# Uncomment this to preserve the line number information for
16+
# debugging stack traces.
17+
#-keepattributes SourceFile,LineNumberTable
18+
19+
# If you keep the line number information, uncomment this to
20+
# hide the original source file name.
21+
#-renamesourcefileattribute SourceFile
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.lvaccaro.alcore
2+
3+
import androidx.test.platform.app.InstrumentationRegistry
4+
import androidx.test.ext.junit.runners.AndroidJUnit4
5+
6+
import org.junit.Test
7+
import org.junit.runner.RunWith
8+
9+
import org.junit.Assert.*
10+
11+
/**
12+
* Instrumented test, which will execute on an Android device.
13+
*
14+
* See [testing documentation](http://d.android.com/tools/testing).
15+
*/
16+
@RunWith(AndroidJUnit4::class)
17+
class ExampleInstrumentedTest {
18+
@Test
19+
fun useAppContext() {
20+
// Context of the app under test.
21+
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22+
assertEquals("com.lvaccaro.alcore", appContext.packageName)
23+
}
24+
}

app/src/main/AndroidManifest.xml

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3+
package="com.lvaccaro.alcore">
4+
5+
<uses-permission android:name="android.permission.INTERNET" />
6+
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
7+
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
8+
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
9+
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
10+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
11+
12+
<application
13+
android:allowBackup="true"
14+
android:icon="@mipmap/ic_launcher"
15+
android:label="@string/app_name"
16+
android:roundIcon="@mipmap/ic_launcher_round"
17+
android:supportsRtl="true"
18+
android:theme="@style/AppTheme">
19+
<activity
20+
android:name=".LogActivity"
21+
android:label="@string/title_activity_log"
22+
android:parentActivityName=".MainActivity"
23+
android:theme="@style/AppTheme.NoActionBar">
24+
<meta-data
25+
android:name="android.support.PARENT_ACTIVITY"
26+
android:value="com.lvaccaro.alcore.MainActivity" />
27+
</activity>
28+
<activity
29+
android:name=".SettingsActivity"
30+
android:label="@string/title_activity_settings"
31+
android:parentActivityName=".MainActivity">
32+
<meta-data
33+
android:name="android.support.PARENT_ACTIVITY"
34+
android:value="com.lvaccaro.alcore.MainActivity" />
35+
</activity>
36+
<activity
37+
android:name=".ConsoleActivity"
38+
android:label="@string/title_activity_console"
39+
android:parentActivityName=".MainActivity">
40+
<meta-data
41+
android:name="android.support.PARENT_ACTIVITY"
42+
android:value="com.lvaccaro.alcore.MainActivity" />
43+
</activity>
44+
<activity android:name=".MainActivity">
45+
<intent-filter>
46+
<action android:name="android.intent.action.MAIN" />
47+
48+
<category android:name="android.intent.category.LAUNCHER" />
49+
</intent-filter>
50+
</activity>
51+
52+
<service
53+
android:name=".LightningService"
54+
android:exported="false" />
55+
</application>
56+
57+
</manifest>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package com.lvaccaro.alcore
2+
3+
import android.os.AsyncTask
4+
import android.os.Build
5+
import android.os.Bundle
6+
import android.text.method.KeyListener
7+
import android.text.method.ScrollingMovementMethod
8+
import android.view.KeyEvent
9+
import android.view.View
10+
import android.view.WindowManager
11+
import android.view.inputmethod.EditorInfo
12+
import android.widget.EditText
13+
import android.widget.ImageButton
14+
import android.widget.Toast
15+
import androidx.appcompat.app.AlertDialog
16+
import com.google.android.material.snackbar.Snackbar
17+
import androidx.appcompat.app.AppCompatActivity
18+
19+
import kotlinx.android.synthetic.main.activity_log.*
20+
import org.jetbrains.anko.doAsync
21+
import java.io.File
22+
import java.lang.Exception
23+
import java.util.*
24+
import kotlin.math.log
25+
26+
class ConsoleActivity : AppCompatActivity() {
27+
28+
lateinit var text: EditText
29+
30+
override fun onCreate(savedInstanceState: Bundle?) {
31+
super.onCreate(savedInstanceState)
32+
setContentView(R.layout.activity_console)
33+
supportActionBar?.setDisplayHomeAsUpEnabled(true)
34+
35+
val editText = findViewById<EditText>(R.id.editText)
36+
text = findViewById<EditText>(R.id.text)
37+
editText.hint = "help"
38+
39+
findViewById<ImageButton>(R.id.send).setOnClickListener {
40+
val text = editText.text.toString()
41+
if (text != "") {
42+
CommandTask().execute(text)
43+
}
44+
}
45+
}
46+
47+
inner class CommandTask : AsyncTask<String, Int, String>() {
48+
49+
lateinit var params: String
50+
override fun onPreExecute() {
51+
super.onPreExecute()
52+
editText.setText("")
53+
}
54+
55+
override fun doInBackground(vararg params: String): String {
56+
this.params = params[0]
57+
val args = params[0].split(" ").toTypedArray()
58+
try {
59+
val res = LightningCli().exec(this@ConsoleActivity, args, false)
60+
val output = LightningCli().toString(res)
61+
return output
62+
}catch (e: Exception) {
63+
e.printStackTrace()
64+
return e.localizedMessage
65+
}
66+
}
67+
68+
override fun onPostExecute(result: String?) {
69+
super.onPostExecute(result)
70+
text.append("$ lightning-cli $params\n")
71+
text.append(result ?: "")
72+
text.append("\n")
73+
}
74+
}
75+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package com.lvaccaro.alcore
2+
3+
import android.content.Context
4+
import android.os.Build
5+
import org.json.JSONObject
6+
import java.io.BufferedReader
7+
import java.io.File
8+
import java.io.InputStream
9+
import java.io.OutputStream
10+
import java.util.logging.Logger
11+
12+
13+
class LightningCli {
14+
15+
val command = "lightning-cli"
16+
val log = Logger.getLogger(LightningService::class.java.name)
17+
18+
@Throws(Exception::class)
19+
fun exec(c: Context, options: Array<String>, json: Boolean = true): InputStream {
20+
val binaryDir = rootDir(c)
21+
val lightningDir = File(rootDir(c), ".lightning")
22+
23+
val args =
24+
arrayOf( String.format("%s/%s", binaryDir.canonicalPath, command),
25+
String.format("--lightning-dir=%s", lightningDir.path),
26+
String.format("--%s", if (json === true) "json" else "raw" ))
27+
28+
val pb = ProcessBuilder((args + options).asList())
29+
pb.directory(binaryDir)
30+
//pb.redirectErrorStream(true)
31+
32+
val process = pb.start()
33+
val code = process.waitFor()
34+
if (code == null || code != 0) {
35+
val error = toString(process.errorStream)
36+
val input = toString(process.inputStream)
37+
log.info(error)
38+
log.info(input)
39+
throw Exception(if(!error.isEmpty()) error else input)
40+
}
41+
return process.inputStream
42+
43+
}
44+
45+
fun toJSONObject(stream: InputStream): JSONObject {
46+
log.info("--- start ---")
47+
val text = toString(stream)
48+
val json = JSONObject(text)
49+
log.info(json.toString())
50+
log.info("--- end ---")
51+
return json
52+
}
53+
54+
fun toString(stream: InputStream): String {
55+
val reader = stream.bufferedReader()
56+
val builder = StringBuilder()
57+
var line = reader.readLine()
58+
while (line != null) {
59+
log.info(line)
60+
if (!line.startsWith("**")) {
61+
builder.append(line)
62+
}
63+
line = reader.readLine()
64+
}
65+
return builder.toString()
66+
}
67+
68+
fun rootDir(c: Context): File {
69+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
70+
return c.noBackupFilesDir
71+
}
72+
return c.filesDir
73+
}
74+
}

0 commit comments

Comments
 (0)