Files
breez-sdk-liquid/packages/react-native/android/src/main/java/com/breezsdkliquid/BreezSDKLiquidModule.kt
Ross Savage 0884106159 Add prepare_lnurl_pay (#524)
* Add prepare_lnurl_pay

* Move fields into prepare response
2024-10-14 10:06:14 +02:00

675 lines
22 KiB
Kotlin

package com.breezsdkliquid
import breez_sdk_liquid.*
import com.facebook.react.bridge.*
import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter
import java.io.File
import java.util.*
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
class BreezSDKLiquidModule(
reactContext: ReactApplicationContext,
) : ReactContextBaseJavaModule(reactContext) {
private lateinit var executor: ExecutorService
private var bindingLiquidSdk: BindingLiquidSdk? = null
companion object {
const val TAG = "RNBreezSDKLiquid"
}
override fun initialize() {
super.initialize()
executor = Executors.newFixedThreadPool(3)
}
override fun getName(): String = TAG
@Throws(SdkException::class)
fun getBindingLiquidSdk(): BindingLiquidSdk {
if (bindingLiquidSdk != null) {
return bindingLiquidSdk!!
}
throw SdkException.Generic("Not initialized")
}
@Throws(SdkException::class)
private fun ensureWorkingDir(workingDir: String) {
try {
val workingDirFile = File(workingDir)
if (!workingDirFile.exists() && !workingDirFile.mkdirs()) {
throw SdkException.Generic("Mandatory field workingDir must contain a writable directory")
}
} catch (e: SecurityException) {
throw SdkException.Generic("Mandatory field workingDir must contain a writable directory")
}
}
@ReactMethod
fun addListener(eventName: String) {}
@ReactMethod
fun removeListeners(count: Int) {}
@ReactMethod
fun defaultConfig(
network: String,
breezApiKey: String,
promise: Promise,
) {
executor.execute {
try {
val networkTmp = asLiquidNetwork(network)
val breezApiKeyTmp = breezApiKey.takeUnless { it.isEmpty() }
val res = defaultConfig(networkTmp, breezApiKeyTmp)
val workingDir = File(reactApplicationContext.filesDir.toString() + "/breezSdkLiquid")
res.workingDir = workingDir.absolutePath
promise.resolve(readableMapOf(res))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun parse(
input: String,
promise: Promise,
) {
executor.execute {
try {
val res = parse(input)
promise.resolve(readableMapOf(res))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun parseInvoice(
input: String,
promise: Promise,
) {
executor.execute {
try {
val res = parseInvoice(input)
promise.resolve(readableMapOf(res))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun setLogger(promise: Promise) {
executor.execute {
try {
val emitter = reactApplicationContext.getJSModule(RCTDeviceEventEmitter::class.java)
setLogger(BreezSDKLiquidLogger(emitter))
promise.resolve(readableMapOf("status" to "ok"))
} catch (e: Exception) {
e.printStackTrace()
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun connect(
req: ReadableMap,
promise: Promise,
) {
if (bindingLiquidSdk != null) {
promise.reject("Generic", "Already initialized")
return
}
executor.execute {
try {
var connectRequest =
asConnectRequest(req) ?: run { throw SdkException.Generic(errMissingMandatoryField("req", "ConnectRequest")) }
ensureWorkingDir(connectRequest.config.workingDir)
bindingLiquidSdk = connect(connectRequest)
promise.resolve(readableMapOf("status" to "ok"))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun addEventListener(promise: Promise) {
executor.execute {
try {
val emitter = reactApplicationContext.getJSModule(RCTDeviceEventEmitter::class.java)
var eventListener = BreezSDKEventListener(emitter)
val res = getBindingLiquidSdk().addEventListener(eventListener)
eventListener.setId(res)
promise.resolve(res)
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun removeEventListener(
id: String,
promise: Promise,
) {
executor.execute {
try {
getBindingLiquidSdk().removeEventListener(id)
promise.resolve(readableMapOf("status" to "ok"))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun getInfo(promise: Promise) {
executor.execute {
try {
val res = getBindingLiquidSdk().getInfo()
promise.resolve(readableMapOf(res))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun signMessage(
req: ReadableMap,
promise: Promise,
) {
executor.execute {
try {
val signMessageRequest =
asSignMessageRequest(req) ?: run { throw SdkException.Generic(errMissingMandatoryField("req", "SignMessageRequest")) }
val res = getBindingLiquidSdk().signMessage(signMessageRequest)
promise.resolve(readableMapOf(res))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun checkMessage(
req: ReadableMap,
promise: Promise,
) {
executor.execute {
try {
val checkMessageRequest =
asCheckMessageRequest(req) ?: run { throw SdkException.Generic(errMissingMandatoryField("req", "CheckMessageRequest")) }
val res = getBindingLiquidSdk().checkMessage(checkMessageRequest)
promise.resolve(readableMapOf(res))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun prepareSendPayment(
req: ReadableMap,
promise: Promise,
) {
executor.execute {
try {
val prepareSendRequest =
asPrepareSendRequest(req) ?: run { throw SdkException.Generic(errMissingMandatoryField("req", "PrepareSendRequest")) }
val res = getBindingLiquidSdk().prepareSendPayment(prepareSendRequest)
promise.resolve(readableMapOf(res))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun sendPayment(
req: ReadableMap,
promise: Promise,
) {
executor.execute {
try {
val sendPaymentRequest =
asSendPaymentRequest(req) ?: run { throw SdkException.Generic(errMissingMandatoryField("req", "SendPaymentRequest")) }
val res = getBindingLiquidSdk().sendPayment(sendPaymentRequest)
promise.resolve(readableMapOf(res))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun prepareReceivePayment(
req: ReadableMap,
promise: Promise,
) {
executor.execute {
try {
val prepareReceiveRequest =
asPrepareReceiveRequest(req)
?: run { throw SdkException.Generic(errMissingMandatoryField("req", "PrepareReceiveRequest")) }
val res = getBindingLiquidSdk().prepareReceivePayment(prepareReceiveRequest)
promise.resolve(readableMapOf(res))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun receivePayment(
req: ReadableMap,
promise: Promise,
) {
executor.execute {
try {
val receivePaymentRequest =
asReceivePaymentRequest(req)
?: run { throw SdkException.Generic(errMissingMandatoryField("req", "ReceivePaymentRequest")) }
val res = getBindingLiquidSdk().receivePayment(receivePaymentRequest)
promise.resolve(readableMapOf(res))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun fetchLightningLimits(promise: Promise) {
executor.execute {
try {
val res = getBindingLiquidSdk().fetchLightningLimits()
promise.resolve(readableMapOf(res))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun fetchOnchainLimits(promise: Promise) {
executor.execute {
try {
val res = getBindingLiquidSdk().fetchOnchainLimits()
promise.resolve(readableMapOf(res))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun preparePayOnchain(
req: ReadableMap,
promise: Promise,
) {
executor.execute {
try {
val preparePayOnchainRequest =
asPreparePayOnchainRequest(req)
?: run { throw SdkException.Generic(errMissingMandatoryField("req", "PreparePayOnchainRequest")) }
val res = getBindingLiquidSdk().preparePayOnchain(preparePayOnchainRequest)
promise.resolve(readableMapOf(res))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun payOnchain(
req: ReadableMap,
promise: Promise,
) {
executor.execute {
try {
val payOnchainRequest =
asPayOnchainRequest(req) ?: run { throw SdkException.Generic(errMissingMandatoryField("req", "PayOnchainRequest")) }
val res = getBindingLiquidSdk().payOnchain(payOnchainRequest)
promise.resolve(readableMapOf(res))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun prepareBuyBitcoin(
req: ReadableMap,
promise: Promise,
) {
executor.execute {
try {
val prepareBuyBitcoinRequest =
asPrepareBuyBitcoinRequest(req)
?: run { throw SdkException.Generic(errMissingMandatoryField("req", "PrepareBuyBitcoinRequest")) }
val res = getBindingLiquidSdk().prepareBuyBitcoin(prepareBuyBitcoinRequest)
promise.resolve(readableMapOf(res))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun buyBitcoin(
req: ReadableMap,
promise: Promise,
) {
executor.execute {
try {
val buyBitcoinRequest =
asBuyBitcoinRequest(req) ?: run { throw SdkException.Generic(errMissingMandatoryField("req", "BuyBitcoinRequest")) }
val res = getBindingLiquidSdk().buyBitcoin(buyBitcoinRequest)
promise.resolve(res)
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun listPayments(
req: ReadableMap,
promise: Promise,
) {
executor.execute {
try {
val listPaymentsRequest =
asListPaymentsRequest(req) ?: run { throw SdkException.Generic(errMissingMandatoryField("req", "ListPaymentsRequest")) }
val res = getBindingLiquidSdk().listPayments(listPaymentsRequest)
promise.resolve(readableArrayOf(res))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun getPayment(
req: ReadableMap,
promise: Promise,
) {
executor.execute {
try {
val reqTmp =
asGetPaymentRequest(req) ?: run { throw SdkException.Generic(errMissingMandatoryField("req", "GetPaymentRequest")) }
val res = getBindingLiquidSdk().getPayment(reqTmp)
promise.resolve(res?.let { readableMapOf(res) })
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun listRefundables(promise: Promise) {
executor.execute {
try {
val res = getBindingLiquidSdk().listRefundables()
promise.resolve(readableArrayOf(res))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun prepareRefund(
req: ReadableMap,
promise: Promise,
) {
executor.execute {
try {
val prepareRefundRequest =
asPrepareRefundRequest(req)
?: run { throw SdkException.Generic(errMissingMandatoryField("req", "PrepareRefundRequest")) }
val res = getBindingLiquidSdk().prepareRefund(prepareRefundRequest)
promise.resolve(readableMapOf(res))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun refund(
req: ReadableMap,
promise: Promise,
) {
executor.execute {
try {
val refundRequest =
asRefundRequest(req) ?: run { throw SdkException.Generic(errMissingMandatoryField("req", "RefundRequest")) }
val res = getBindingLiquidSdk().refund(refundRequest)
promise.resolve(readableMapOf(res))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun rescanOnchainSwaps(promise: Promise) {
executor.execute {
try {
getBindingLiquidSdk().rescanOnchainSwaps()
promise.resolve(readableMapOf("status" to "ok"))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun sync(promise: Promise) {
executor.execute {
try {
getBindingLiquidSdk().sync()
promise.resolve(readableMapOf("status" to "ok"))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun recommendedFees(promise: Promise) {
executor.execute {
try {
val res = getBindingLiquidSdk().recommendedFees()
promise.resolve(readableMapOf(res))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun backup(
req: ReadableMap,
promise: Promise,
) {
executor.execute {
try {
val backupRequest =
asBackupRequest(req) ?: run { throw SdkException.Generic(errMissingMandatoryField("req", "BackupRequest")) }
getBindingLiquidSdk().backup(backupRequest)
promise.resolve(readableMapOf("status" to "ok"))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun restore(
req: ReadableMap,
promise: Promise,
) {
executor.execute {
try {
val restoreRequest =
asRestoreRequest(req) ?: run { throw SdkException.Generic(errMissingMandatoryField("req", "RestoreRequest")) }
getBindingLiquidSdk().restore(restoreRequest)
promise.resolve(readableMapOf("status" to "ok"))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun disconnect(promise: Promise) {
executor.execute {
try {
getBindingLiquidSdk().disconnect()
bindingLiquidSdk = null
promise.resolve(readableMapOf("status" to "ok"))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun prepareLnurlPay(
req: ReadableMap,
promise: Promise,
) {
executor.execute {
try {
val prepareLnUrlPayRequest =
asPrepareLnUrlPayRequest(req)
?: run { throw SdkException.Generic(errMissingMandatoryField("req", "PrepareLnUrlPayRequest")) }
val res = getBindingLiquidSdk().prepareLnurlPay(prepareLnUrlPayRequest)
promise.resolve(readableMapOf(res))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun lnurlPay(
req: ReadableMap,
promise: Promise,
) {
executor.execute {
try {
val lnUrlPayRequest =
asLnUrlPayRequest(req) ?: run { throw SdkException.Generic(errMissingMandatoryField("req", "LnUrlPayRequest")) }
val res = getBindingLiquidSdk().lnurlPay(lnUrlPayRequest)
promise.resolve(readableMapOf(res))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun lnurlWithdraw(
req: ReadableMap,
promise: Promise,
) {
executor.execute {
try {
val lnUrlWithdrawRequest =
asLnUrlWithdrawRequest(req)
?: run { throw SdkException.Generic(errMissingMandatoryField("req", "LnUrlWithdrawRequest")) }
val res = getBindingLiquidSdk().lnurlWithdraw(lnUrlWithdrawRequest)
promise.resolve(readableMapOf(res))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun lnurlAuth(
reqData: ReadableMap,
promise: Promise,
) {
executor.execute {
try {
val lnUrlAuthRequestData =
asLnUrlAuthRequestData(reqData)
?: run { throw SdkException.Generic(errMissingMandatoryField("reqData", "LnUrlAuthRequestData")) }
val res = getBindingLiquidSdk().lnurlAuth(lnUrlAuthRequestData)
promise.resolve(readableMapOf(res))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun registerWebhook(
webhookUrl: String,
promise: Promise,
) {
executor.execute {
try {
getBindingLiquidSdk().registerWebhook(webhookUrl)
promise.resolve(readableMapOf("status" to "ok"))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun unregisterWebhook(promise: Promise) {
executor.execute {
try {
getBindingLiquidSdk().unregisterWebhook()
promise.resolve(readableMapOf("status" to "ok"))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun fetchFiatRates(promise: Promise) {
executor.execute {
try {
val res = getBindingLiquidSdk().fetchFiatRates()
promise.resolve(readableArrayOf(res))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun listFiatCurrencies(promise: Promise) {
executor.execute {
try {
val res = getBindingLiquidSdk().listFiatCurrencies()
promise.resolve(readableArrayOf(res))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
}