package com.example.my-wallet
import com.algorand.algosdk.transaction.Transaction
import com.algorand.algosdk.util.Encoder
import foundation.algorand.crypto.EncoderType
import foundation.algorand.crypto.avm.KeyPairs
import foundation.algorand.provider.Message
import foundation.algorand.provider.avm.models.*
import java.security.KeyPair
import kotlin.io.encoding.Base64
import kotlin.io.encoding.ExperimentalEncodingApi
* A provider for the Algorand Virtual Machine (AVM).
* Used to test the provider.avm.models package.
class AVMProvider(val providerId: String) {
val encoder = foundation.algorand.crypto.avm.Encoder()
var keyPair: KeyPair? = null
* Handle a message from a channel
fun handleRequestMessage(msg: Message, keyPair: KeyPair): Any {
val message = encoder.decode<RequestMessage>(msg.data, msg.encoding)
// Handle the message references
when (message.reference) {
"arc0027:sign_transactions:request" -> {
val request = encoder.decode<SignTransactionsParams>(
encoder.encode(message.params, EncoderType.NONE), EncoderType.NONE
return processSignTransactions(request)
throw IllegalArgumentException("Invalid reference: ${message.reference}")
* Decode Unsigned Transaction
@OptIn(ExperimentalEncodingApi::class)
private fun decodeUnsignedTransaction(unsignedTxn: String): Transaction? {
return Encoder.decodeFromMsgPack(Base64.decode(unsignedTxn), Transaction::class.java)
* Process the Sign Transactions Requests
@OptIn(ExperimentalEncodingApi::class)
fun processSignTransactions(params: SignTransactionsParams): SignTransactionsResult {
require(params.validate())
val signedTxns = mutableListOf<String>()
params.txns.forEach { txn ->
val inst = decodeUnsignedTransaction(txn.txn!!)
val signature = KeyPairs.rawSignBytes(inst!!.bytesToSign(), this.keyPair!!.private)
signedTxns.add(Base64.UrlSafe.encode(signature!!))
// Create the response payload
return SignTransactionsResult(providerId, signedTxns)