Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
tech.pylons.ipc.Message.kt Maven / Gradle / Ivy
package tech.pylons.ipc
import com.beust.klaxon.JsonArray
import com.beust.klaxon.JsonObject
import com.beust.klaxon.Parser
import tech.pylons.lib.PubKeyUtil
import tech.pylons.lib.core.ICore
import tech.pylons.lib.core.IMulticore
import org.apache.tuweni.bytes.Bytes32
import java.lang.StringBuilder
import java.util.*
import kotlin.reflect.full.*
import tech.pylons.lib.klaxon
import tech.pylons.lib.types.*
import tech.pylons.lib.types.credentials.CosmosCredentials
import tech.pylons.lib.types.tx.Coin
import java.io.StringReader
sealed class Message {
class CancelTrade (
var tradeId : String? = null
) : Message() {
companion object {
fun deserialize(json : String) = klaxon.parse(json)
}
override fun resolve() = Response.emit(this, true,
txs = listOf(core!!.cancelTrade(tradeId!!)), tradesIn = listOf(tradeId!!))
}
class CheckExecution(
var id : String? = null,
var payForCompletion : Boolean? = null
) : Message() {
companion object {
fun deserialize(json : String) = klaxon.parse(json)
}
override fun resolve() = Response.emit(this, true,
txs = listOf(core!!.checkExecution(id!!, payForCompletion!!)))
// we need structured exec data but we can't do it atm
}
class CreateCookbooks(
var ids : List? = null,
var names : List? = null,
var developers : List? = null,
var descriptions : List? = null,
var versions : List? = null,
var supportEmails : List? = null,
var costsPerBlock : List? = null
) : Message() {
companion object {
fun deserialize(json : String) = klaxon.parse(json)
}
override fun resolve() = Response.emit(this, true,
txs = core!!.batchCreateCookbook(ids!!, names!!, developers!!,
descriptions!!, versions!!, supportEmails!!, costsPerBlock!!))
}
class CreateRecipes(
var names : List? = null,
var cookbooks : List? = null,
var descriptions : List? = null,
var blockIntervals : List? = null,
var coinInputs : List? = null,
var itemInputs: List? = null,
var outputTables : List? = null,
var outputs : List? = null,
var extraInfos : List? = null
) : Message() {
companion object {
fun deserialize(json : String) = klaxon.parse(json)
}
override fun resolve() = Response.emit(this, true, txs = core!!.batchCreateRecipe(names!!, cookbooks!!,
descriptions!!, blockIntervals!!, coinInputs!!, itemInputs!!, outputTables!!, outputs!!, extraInfos!!),
cookbooksIn = cookbooks!!)
}
class CreateTrade (
var coinInputs : List? = null,
var itemInputs: List? = null,
var coinOutputs: List? = null,
var itemOutputs : List? = null,
var extraInfo : String? = null
) : Message() {
companion object {
fun deserialize(json : String) = klaxon.parse(json)
}
override fun resolve() = Response.emit(this, true,
txs = listOf(core!!.createTrade(coinInputs!!, itemInputs!!, coinOutputs!!, itemOutputs!!, extraInfo!!)))
// this feels like it should have some structured input data but i'm not sure atm, need to look at how trades
// work on the node some more
}
class DisableRecipes (
var recipes : List? = null
) : Message() {
companion object {
fun deserialize(json: String) = klaxon.parse(json)
}
override fun resolve() = Response.emit(this, true,
txs = core!!.batchDisableRecipe(recipes!!), recipesIn = recipes!!)
}
class EnableRecipes (
var recipes : List? = null
) : Message() {
companion object {
fun deserialize(json: String) = klaxon.parse(json)
}
override fun resolve() = Response.emit(this, true,
txs = core!!.batchEnableRecipe(recipes!!), recipesIn = recipes!!)
}
class ExecuteRecipe(
var recipe : String? = null,
var cookbook : String? = null,
var itemInputs : List? = null
) : Message() {
companion object {
fun deserialize(json: String) = klaxon.parse(json)
}
override fun resolve() = Response.emit(this, true,
txs = listOf(core!!.applyRecipe(recipe!!, cookbook!!, itemInputs!!)),
recipesIn = listOf(recipe!!), cookbooksIn = listOf(cookbook!!),
itemsIn = itemInputs!!)
}
class FulfillTrade(
var tradeId : String? = null,
var itemIds : List? = null,
var paymentId: String? = null
) : Message() {
companion object {
fun deserialize(json : String) = klaxon.parse(json)
}
override fun resolve() = Response.emit(this, true,
txs = listOf(core!!.fulfillTrade(tradeId!!, itemIds!!)),
tradesIn = listOf(tradeId!!), itemsIn = itemIds!!)
}
class GetCookbooks : Message() {
companion object {
fun deserialize(json : String) = klaxon.parse(json)
}
override fun resolve() = Response.emit(this, true,
cookbooksOut = core!!.getCookbooks())
}
class GetPendingExecutions : Message() {
companion object {
fun deserialize(json : String) = klaxon.parse(json)
}
override fun resolve() = Response.emit(this, true,
executionsOut = core!!.getPendingExecutions())
}
class GetTrades : Message() {
companion object {
fun deserialize(json : String) = klaxon.parse(json)
}
override fun resolve() = Response.emit(this, true,
tradesOut = core!!.listTrades())
}
class GetProfile(
var address : String? = null
) : Message() {
companion object {
fun deserialize(json : String) = klaxon.parse(json)
}
override fun resolve(): Response {
val p = core!!.getProfile(address)
val ls = mutableListOf()
if (p != null) ls.add(Profile(p.address, p.strings, p.coins, p.items)) // hack because klaxon will die if we aren't specifically an instance of the base class
println("GetProfile Response")
return Response.emit(this, true, profilesOut = ls)
}
}
class GetPylons(
var count : Long? = null
) : Message() {
companion object {
fun deserialize(json : String) = klaxon.parse(json)
}
override fun resolve() = Response.emit(this, true,
txs = listOf(core!!.getPylons(count!!)))
}
class GetRecipes : Message() {
companion object {
fun deserialize(json : String) = klaxon.parse(json)
}
override fun resolve() = Response.emit(this, true,
recipesOut = core!!.getRecipes())
}
class GetRecipesBySender(): Message() {
companion object {
fun deserialize(json: String) = klaxon.parse(json)
}
override fun resolve() = Response.emit(this, true,
recipesOut = core!!.getRecipesBySender())
}
class GoogleIapGetPylons(
var productId : String? = null,
var purchaseToken : String? = null,
var receiptData : String? = null,
var signature : String? = null
) : Message() {
companion object {
fun deserialize(json : String) = klaxon.parse(json)
}
override fun resolve() = Response.emit(this, true,
txs = listOf(core!!.googleIapGetPylons(productId!!, purchaseToken!!, receiptData!!, signature!!)))
}
class GetTransaction(
var txHash : String? = null
) : Message() {
companion object {
fun deserialize(json : String) = klaxon.parse(json)
}
override fun resolve() = Response.emit(this, true, txs = listOf(core!!.getTransaction(txHash!!)))
}
class RegisterProfile(
var name : String? = null,
var makeKeys : Boolean? = null
) : Message() {
companion object {
fun deserialize(json : String) = klaxon.parse(json)
}
override fun resolve(): Response {
if (IMulticore.enabled && makeKeys == true) {
IMulticore.instance!!.addCore(null)
makeKeys = false // we made the keys!
}
val tx = when (makeKeys!!) {
// HACK: We shouldn't accept empty name field once names actually exist on the backend
true -> core!!.newProfile(name.orEmpty())
false -> core!!.newProfile(name.orEmpty(), core!!.engine.cryptoHandler.keyPair)
}
return Response.emit(this, true, txs = listOf(tx))
}
}
class SendCoins(
var coins : String?,
var receiver : String?
) : Message() {
companion object {
fun deserialize(json : String) = klaxon.parse(json)
}
override fun resolve() = Response.emit(this, true, txs = listOf(core!!.sendCoins(coins!!, receiver!!)),
coinsIn = Coin.listFromJson(klaxon.parseJsonArray(StringReader(coins)) as JsonArray))
}
class SetItemString(
var itemId : String? = null,
var field : String? = null,
var value : String? = null
) : Message() {
companion object {
fun deserialize(json: String) = klaxon.parse(json)
}
override fun resolve() = Response.emit(this, true, txs = listOf(core!!.setItemString(itemId!!, field!!, value!!)),
itemsIn = listOf(itemId!!))
}
class UpdateCookbooks(
var ids : List? = null,
var names : List? = null,
var developers : List? = null,
var descriptions : List? = null,
var versions : List? = null,
var supportEmails : List? = null
) : Message() {
companion object {
fun deserialize(json : String) = klaxon.parse(json)
}
override fun resolve() = Response.emit(this, true, txs =
core!!.batchUpdateCookbook(names!!, developers!!, descriptions!!, versions!!, supportEmails!!, ids!!),
cookbooksIn = ids!!)
}
class UpdateRecipes(
var ids : List? = null,
var names : List? = null,
var cookbooks : List? = null,
var descriptions : List? = null,
var blockIntervals : List? = null,
var coinInputs : List? = null,
var itemInputs: List? = null,
var outputTables : List? = null,
var outputs : List? = null,
var extraInfos: List? = null
) : Message() {
companion object {
fun deserialize(json : String) = klaxon.parse(json)
}
override fun resolve() : Response =
Response.emit(this, true, txs = core!!.batchUpdateRecipe(ids!!, names!!, cookbooks!!,
descriptions!!, blockIntervals!!, coinInputs!!, itemInputs!!, outputTables!!,
outputs!!, extraInfos!!),
recipesIn = ids!!, cookbooksIn = cookbooks!!)
}
class WalletServiceTest(
val input : String? = null
) : Message() {
companion object {
fun deserialize(json: String) = klaxon.parse(json)
}
override fun resolve() = Response.emit(this, true, unstructured = listOf(core!!.walletServiceTest(input!!)))
}
class WalletUiTest : Message() {
companion object {
fun deserialize(json: String) = klaxon.parse(json)
}
override fun ui(): UiHook {
// WalletUiTest never returns until this hook is released
return UILayer.addUiHook(UiHook(this))
}
override fun resolve() = Response.emit(this, true, unstructured = listOf(core!!.walletUiTest()))
}
class ExportKeys : Message() {
companion object {
fun deserialize(json : String) = klaxon.parse(json)
}
override fun resolve(): Response {
val keys = core!!.dumpKeys()
return Response.emit(this, true, unstructured = listOf(core!!.userProfile!!.address, core!!.userProfile!!.strings["name"].orEmpty(),
keys[0], keys[1]))
}
}
class AddKeypair(
val privkey : String? = null
) : Message() {
companion object{
fun deserialize(json : String) = klaxon.parse(json)
}
override fun resolve(): Response {
if (!IMulticore.enabled) throw Exception("Multicore is not enabled")
val kp = PylonsSECP256K1.KeyPair.fromSecretKey(
PylonsSECP256K1.SecretKey.fromBytes(Bytes32.fromHexString(privkey!!)))
val credentials = CosmosCredentials(PubKeyUtil.getAddressString(PubKeyUtil.getAddressFromKeyPair(kp).toArray()))
IMulticore.instance!!.addCore(kp)
return Response.emit(this, true, profilesOut = listOf(core!!.getProfile(credentials.address)!!))
}
}
class SwitchKeys : Message() {
val address : String? = null
companion object{
fun deserialize(json : String) = klaxon.parse(json)
}
override fun resolve(): Response {
if (!IMulticore.enabled) throw Exception("Multicore is not enabled")
val core = IMulticore.instance!!.switchCore(address!!)
return Response.emit(this, true, profilesOut = listOf(core.getProfile(address)!!))
}
}
/**
* BuyPylons
* do wallet UI action for buy pylons
* wallet ui set txHash of the Purchase Transaction
* return Purchase Transaction to counterpart
*/
class BuyPylons: Message() {
//
var txHash:String? = null
companion object{
fun deserialize(json: String) = klaxon.parse(json)
}
override fun resolve(): Response {
//transactions can fail
if (txHash.isNullOrEmpty()) {
return Response.emit(this, true)
}
return Response.emit(this, true,
txs=listOf(core!!.getTransaction(txHash!!))
)
}
}
companion object {
protected var core : ICore? = null
fun useCore(core : ICore) {
Companion.core = core
}
fun match(json: String) : Message? {
println("Trying to match message \n$json")
val jsonObject = Parser.default().parse(StringBuilder(json)) as JsonObject
IPCLayer.implementation!!.messageId = jsonObject.int("messageId")!!
println("Set messageId to ${IPCLayer.implementation!!.messageId}")
val cid = jsonObject.int("clientId")
val mid = jsonObject.int("walletId")
if (cid != IPCLayer.implementation!!.clientId || mid != IPCLayer.implementation!!.walletId)
throw Exception("Client/wallet ID mismatch - got ${jsonObject.int("clientId").toString()} ${jsonObject.int("walletId").toString()}, expected ${IPCLayer.implementation!!.clientId} ${IPCLayer.implementation!!.walletId}")
val type = jsonObject.string("type")!!
val msg =
Base64.getDecoder().decode(
jsonObject.string("msg")!!).toString(Charsets.US_ASCII)
var ret : Message? = null
Message::class.sealedSubclasses.forEach { kClass ->
if (kClass.simpleName == type) {
println("attempting to match ${kClass.simpleName}")
val func = kClass.companionObject?.functions?.find { it.name == "deserialize" }
ret = func?.call(kClass.companionObjectInstance, msg) as Message?
}
}
return ret
}
}
open class UiHook(val msg : Message) {
var response : Response? = null
var live : Boolean = true
private set
var confirmed : Boolean = false
private set
var rejected: Boolean = false
private set
fun confirm() : UiHook {
confirmed = true
return this
}
fun reject() : UiHook {
rejected = true
return this
}
fun release() : UiHook {
live = false
return this
}
}
open fun ui () : UiHook {
// Default ui() implementation just forces the ui hook through its entire lifecycle immediately.
// This simplifies the way we need to deal w/ UI interactions - every message creates
// a ui hook; it's just that some of them don't actually need to do any work before they're
// done with it.
//return UILayer.releaseUiHook(UILayer.confirmUiHook(UILayer.addUiHook(UiHook(this))))
//break main ui loop
return UILayer.addUiHook(UiHook(this))
}
abstract fun resolve() : Response
}