XYOracleNetwork/sdk-xyo-client-android

View on GitHub
sdk/src/main/java/network/xyo/client/boundwitness/XyoBoundWitnessBuilder.kt

Summary

Maintainability
A
0 mins
Test Coverage
package network.xyo.client.boundwitness

import android.os.Build
import androidx.annotation.RequiresApi
import network.xyo.client.XyoSerializable
import network.xyo.client.XyoWitness
import network.xyo.client.address.XyoAccount
import network.xyo.client.payload.XyoPayload
import network.xyo.client.payload.XyoValidationException

@RequiresApi(Build.VERSION_CODES.M)
open class XyoBoundWitnessBuilder {
    protected var _witnesses = mutableListOf<XyoAccount>()
    protected var _previous_hashes = mutableListOf<String?>()
    protected var _payload_hashes = mutableListOf<String>()
    protected var _payload_schemas = mutableListOf<String>()
    protected var _payloads = mutableListOf<XyoPayload>()

    open fun witness(account: XyoAccount, previousHash: String?): XyoBoundWitnessBuilder {
        _witnesses.add(account)
        _previous_hashes.add(previousHash)
        return this
    }

    open fun witnesses(witnesses: List<XyoWitness<XyoPayload>>): XyoBoundWitnessBuilder {
        witnesses.forEach { witness -> _witnesses.add(witness.address) }
        witnesses.forEach { witness -> _previous_hashes.add(witness.previousHash) }
        return this
    }

    open fun hashableFields(): XyoBoundWitnessBodyJson {
        return XyoBoundWitnessBodyJson(
            _witnesses.map { witness -> witness.address.hex},
            _previous_hashes,
            _payload_hashes,
            _payload_schemas
        )
    }

    @Throws(XyoValidationException::class)
    fun <T: XyoPayload>payload(schema: String, payload: T): XyoBoundWitnessBuilder {
        payload.validate()
        _payloads.add(payload)
        _payload_hashes.add(XyoSerializable.sha256String(payload))
        _payload_schemas.add(schema)
        return this
    }

    @Throws(XyoValidationException::class)
    fun payloads(payloads: List<XyoPayload>): XyoBoundWitnessBuilder {
        payloads.forEach {
            payload(it.schema, it)
        }
        return this
    }

    fun sign(hash: String): List<String> {
        return _witnesses.map {
            val sig = XyoSerializable.bytesToHex(it.private.sign(hash))
            sig
        }
    }

    protected fun  constructFields(bw: XyoBoundWitnessJson, previousHash: String?) {
        val hashable = hashableFields()
        val hash = XyoSerializable.sha256String(hashable)
        bw._previous_hash = previousHash
        bw._signatures = this.sign(hash)
        bw._hash = hash
        bw._client = "android"
        bw._payloads = _payloads
        bw.addresses = _witnesses.map { witness -> witness.address.hex}
        bw.payload_hashes = _payload_hashes
        bw.payload_schemas = _payload_schemas
        bw.previous_hashes = _previous_hashes
    }

    open fun build(previousHash: String? = null): XyoBoundWitnessJson {
        val bw = XyoBoundWitnessJson().let{
            constructFields(it, previousHash)
            it
        }
        return bw
    }
}