Skip to content

Commit

Permalink
Solution proposed about the issue clightning4j#20
Browse files Browse the repository at this point in the history
  • Loading branch information
vincenzopalazzo committed Jul 19, 2020
1 parent be22e7e commit e939517
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 606 deletions.
141 changes: 0 additions & 141 deletions app/src/main/java/com/lvaccaro/lamp/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,14 @@ import com.google.zxing.WriterException
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel
import com.google.zxing.qrcode.encoder.Encoder
import com.lvaccaro.lamp.Channels.ChannelsActivity
import com.lvaccaro.lamp.Channels.FundChannelFragment
import com.lvaccaro.lamp.Services.LightningService
import com.lvaccaro.lamp.Services.TorService
import com.lvaccaro.lamp.ui.send.SentToBitcoinFragment
import com.lvaccaro.lamp.util.LampKeys
import com.lvaccaro.lamp.util.Validator
import org.jetbrains.anko.doAsync
import org.json.JSONArray
import org.json.JSONObject
import java.lang.Exception
import java.util.*
import java.util.logging.Logger
import kotlin.collections.HashMap
import kotlin.concurrent.schedule


Expand Down Expand Up @@ -634,134 +629,6 @@ class MainActivity : UriResultActivity() {
stopTorService()
}

fun scanned(text: String) {
try {
Log.d(TAG, "******** Text from scan View *********\n${text}")
val result = isBitcoinPayment(text.trim())
/**
* TODO(vincenzopalazzo): This code in case of exception inside the if below we have the
* following print debug
*
* 2020-07-14 00:43:52.114 17279-17497/com.lvaccaro.lamp D/MainActivity: ***** Bitcoin Address *****
* 020-07-14 00:43:52.114 17279-17497/com.lvaccaro.lamp D/MainActivity: ***** RUNNING withdraw command *****
* 2020-07-14 00:43:52.115 17279-17497/com.lvaccaro.lamp D/MainActivity: ***** RUNNING connect command *****
*
* FIXME: Maybe we can use the Validator to se if is the invoice of the node url
* In some cases I noted that the invoice use the beach32 format,
* so it contains also the network flag.
* In the other head we know tha the node contains the @ and
* maybe if I'm not loasing somethings, the id has only numbers
*/
if(result.isNotEmpty()){
Log.d(TAG, "***** RUNNING withdraw command *****")
doWithDrawCommand(result)
return
}
Log.d(TAG, "***** RUNNING decodepay command *****")
val res = cli.exec(this@MainActivity, arrayOf("decodepay", text), true).toText()
runOnUiThread { showDecodePay(text, res) }
} catch (e: Exception) {
e.printStackTrace()
try {
Log.d(TAG, "***** RUNNING connect command *****")
val res = cli.exec(this@MainActivity, arrayOf("connect", text), true).toJSONObject()
runOnUiThread { showConnected(res["id"] as String) }
} catch (e: Exception) {
runOnUiThread {
showToast( e.localizedMessage, Toast.LENGTH_LONG)
}
}
}
}

private fun isBitcoinPayment(text: String): Map<String, String> {
var result = HashMap<String, String>()
//We know that we have two type of url that can arrive from QR
//This type are URL like bitcoin:ADDRESS?amount=10.00
//OR
//The other type, so the QR can contains only the address
if(Validator.isBitcoinAddress(text)){
Log.d(TAG, "***** Bitcoin Address *****")
result.put(LampKeys.ADDRESS_KEY, text)
}else if(Validator.isBitcoinURL(text)){
Log.d(TAG, "***** Bitcoin URL *****")
result = Validator.doParseBitcoinURL(text)
}
return result
}

private fun doWithDrawCommand(result: Map<String, String>) {
val address = result[LampKeys.ADDRESS_KEY]
lateinit var amount: String
if(!result.containsKey(LampKeys.AMOUNT_KEY)) {
//In this cases I set the amount to all and inside the dialog the used
//can modify the value (if want).
amount = "all"
}else{
//TODO (vincenzopalazzo) In can choose inside the App setting the unit of bitcoin
//that the used want use inside the app.
//In addition, in this cases I will start the activity to require more information?
//For instance, feerate and minconf? Maybe with an advanced setting with combobox
amount = (result[LampKeys.AMOUNT_KEY]!!.toDouble() * 100000000).toLong().toString()
// amount = result[LampKeys.AMOUNT_KEY]!!
}

val sentToBitcoinDialog = SentToBitcoinFragment()
val bundle = Bundle()
bundle.putString("address", address)
bundle.putString("amount", amount)
sentToBitcoinDialog.arguments = bundle
val fragmentTransaction = supportFragmentManager.beginTransaction()
fragmentTransaction.add(sentToBitcoinDialog, "SentToBitcoinFragment")
fragmentTransaction.commitAllowingStateLoss()
}

fun showDecodePay(bolt11: String, decoded: String) {
AlertDialog.Builder(this@MainActivity)
.setTitle("decodepay")
.setMessage(decoded.toString())
.setCancelable(true)
.setPositiveButton("pay") { dialog, which ->
try {
cli.exec(this@MainActivity, arrayOf("pay", bolt11), true)
.toJSONObject()
runOnUiThread {
Toast.makeText(
this@MainActivity,
"Invoice paid",
Toast.LENGTH_LONG
).show()
}
} catch (e: Exception) {
runOnUiThread {
Toast.makeText(
this@MainActivity,
e.localizedMessage,
Toast.LENGTH_LONG
).show()
}
}
}
.setNegativeButton("cancel") { dialog, which -> }
.show()
}

fun showConnected(id: String) {
AlertDialog.Builder(this@MainActivity)
.setTitle("connect")
.setMessage(id)
.setPositiveButton("fund channel") { dialog, which ->
val bottomSheetDialog =
FundChannelFragment()
val args = Bundle()
args.putString("uri", id)
bottomSheetDialog.arguments = args
bottomSheetDialog.show(supportFragmentManager, "Fund channel")
}
.setNegativeButton("cancel") { dialog, which -> }
.show()
}

fun generateNewAddress() {
val res = cli.exec(
this@MainActivity,
Expand Down Expand Up @@ -797,14 +664,6 @@ class MainActivity : UriResultActivity() {
}
}

private fun showSnackBar(message: String, duration: Int){
Snackbar.make(findViewById(android.R.id.content), message, duration).show()
}

private fun showToast(message: String, duration: Int){
Toast.makeText(applicationContext, message, duration).show()
}

fun copyToClipboard(key: String, text: String) {
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clip: ClipData = ClipData.newPlainText(key, text)
Expand Down
64 changes: 20 additions & 44 deletions app/src/main/java/com/lvaccaro/lamp/UriResultActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.snackbar.Snackbar
import com.lvaccaro.lamp.Channels.FundChannelFragment
import com.lvaccaro.lamp.Services.CLightningException
import com.lvaccaro.lamp.util.LampKeys
Expand All @@ -28,7 +29,6 @@ open class UriResultActivity() : AppCompatActivity() {
if (isBitcoinAddress) {
val parm = HashMap<String, String>()
Log.d(TAG, "*** Bitcoin address")
//resultCommand = runCommandCLightning(LampKeys.WITHDRAW_COMMAND, arrayOf(text))
parm.put(LampKeys.ADDRESS_KEY, text)
runOnUiThread {
showWithdraw(parm)
Expand Down Expand Up @@ -58,48 +58,19 @@ open class UriResultActivity() : AppCompatActivity() {
if(resultCommand == null){
return
}
var message = ""
if(resultCommand.has(LampKeys.MESSAGE_JSON_KEY)){
message = resultCommand.get(LampKeys.MESSAGE_JSON_KEY).toString()
}else if(resultCommand.has("id")){
message = "Connected to node"
}
runOnUiThread {
showToastMessage(
resultCommand.toString(),
message,
Toast.LENGTH_LONG
)
}
}

/*
try {
val res = cli.exec(this, arrayOf("decodepay", text), true).toText()
runOnUiThread { showDecodePay(text, res) }
return
} catch (e: Exception) {
Log.d(TAG, "decodepay: ${e.localizedMessage}")
}
try {
val res = cli.exec(this, arrayOf("connect", text), true).toJSONObject()
runOnUiThread { showConnect(res["id"] as String) }
return
} catch (e: Exception) {
Log.d(TAG, "connect: ${e.localizedMessage}")
}
//TODO(vincenzopalazzo) this function not work with the URI like the string below
//bitcoin:tb1qzy5mqyqpl6p67x8psu2phxwp0e7lz79w47e5ad
try {
// pre-parsing text to avoid multi strings text
val address = text.split(" ").first()
cli.exec(this, arrayOf("withdraw", address), true).toJSONObject()
return
} catch (e: Exception) {
val res = JSONObject(e.localizedMessage)
val message = res["message"] as String
// withdraw fails due by missing satoshi field
if (message == "missing required parameter: satoshi") {
runOnUiThread { showWithdraw(text) }
return
}
Log.d(TAG, "withdraw: ${e.localizedMessage}")
}*/
}

fun runCommandCLightning(command: String, parameter: Array<String>): JSONObject {
Expand All @@ -120,13 +91,6 @@ open class UriResultActivity() : AppCompatActivity() {
}
}

fun showToastMessage(message: String, duration: Int) {
Toast.makeText(
this, message,
duration
).show()
}

private fun showDecodePay(bolt11: String, decoded: String) {
AlertDialog.Builder(this)
.setTitle("decodepay")
Expand Down Expand Up @@ -187,4 +151,16 @@ open class UriResultActivity() : AppCompatActivity() {
bottomSheetDialog.arguments = bundle
bottomSheetDialog.show(supportFragmentManager, "WithdrawFragment")
}

protected fun showToastMessage(message: String, duration: Int) {
if(message.isEmpty()) return
Toast.makeText(
this, message,
duration
).show()
}

protected fun showSnackBar(message: String, duration: Int){
Snackbar.make(findViewById(android.R.id.content), message, duration).show()
}
}
29 changes: 24 additions & 5 deletions app/src/main/java/com/lvaccaro/lamp/WithdrawFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@ import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.core.widget.addTextChangedListener
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.google.android.material.switchmaterial.SwitchMaterial
import com.lvaccaro.lamp.util.LampKeys
import kotlinx.android.synthetic.main.list_tx.*
import org.jetbrains.anko.doAsync
Expand All @@ -27,13 +31,28 @@ class WithdrawFragment: BottomSheetDialogFragment() {
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_withdraw, container, false)
val address = arguments?.getString(LampKeys.ADDRESS_KEY)
val satoshi = arguments?.getString(LampKeys.AMOUNT_KEY)
view.findViewById<TextView>(R.id.addressText).text = address ?: ""
view.findViewById<TextView>(R.id.satoshiText).text = satoshi ?: ""
val address = arguments?.getString(LampKeys.ADDRESS_KEY) ?: ""
val satoshi = arguments?.getString(LampKeys.AMOUNT_KEY) ?: ""
view.findViewById<TextView>(R.id.addressText).text = address
view.findViewById<TextView>(R.id.satoshiText).text = satoshi
view.findViewById<TextView>(R.id.satoshiText).addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) { }

override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}

override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
view.findViewById<SwitchMaterial>(R.id.switch_send_all).isChecked = s?.length == 0
}
})
view.findViewById<SwitchMaterial>(R.id.switch_send_all).isChecked = satoshi.trim().isEmpty()
view.findViewById<Button>(R.id.confirmButton).setOnClickListener {
val satoshi = view.findViewById<TextView>(R.id.satoshiText).text.toString()
var satoshi = view.findViewById<TextView>(R.id.satoshiText).text.toString()
val address = view.findViewById<TextView>(R.id.addressText).text.toString()

val sendAll = view.findViewById<SwitchMaterial>(R.id.switch_send_all).isChecked
if(sendAll) satoshi = "all"

doAsync { withdraw(address, satoshi) }
}
return view
Expand Down
Loading

0 comments on commit e939517

Please sign in to comment.