Skip to content

Using Appkit from Python

Benjamin Schulte edited this page Mar 6, 2022 · 8 revisions

To use Appkit from Python, you need to bridge to a JVM instance running the Appkit code. To do so, we use JPype for this guide. It is presumed that you've already set up a proper Python environment.

General setup

Install jpype in your Python environment by typing

pip install JPype1

(or pip3 when using Python3).

For Appkit to work on your system, you'll need a JDK8 or JDK11 installed and you need the appkit "fat jar", that means a jar containing all dependencies to add to your project.

The general wrapper for your Python code is then something like this:

# Enable Java imports
import jpype.imports

# Pull in types
from jpype.types import *

# Launch the JVM
jpype.startJVM()
# Add Appkit fat jar to JVM claspath
jpype.addClassPath("ergo-appkit-fat-jar.jar")

import java.lang

# ----> add your ergo related code here

jpype.shutdownJVM()

You have two options to implement your ergo related code: You can do everything in your Python code and call all necessary Appkit methods from Python, or you create an own Java/Kotlin/Scala project and implement your necessary logic in these languages providing some methods for simpler use from Python.

A general recommendation which approach is more useful can't be given - while Appkit is a bit more easier to use from JVM, you most likely are more comfortable coding Python if you read this guide, so you might prefer using Python.

A downside is that code completion is not working for Appkit methods within Python (or at least there was no way found so far). The good news is that most things work pretty straightforward so code completion is not a must have.

Construct an Ergo transaction

Let's take a look on how to construct an ergo transaction in Appkit. In Java this is done the following way:

    // file header
    import org.ergoplatform.appkit.Address;
    import org.ergoplatform.appkit.BoxOperations;
    import org.ergoplatform.appkit.NetworkType;
    import org.ergoplatform.appkit.RestApiErgoClient;

    // within a method
    NetworkType networkType = NetworkType.TESTNET;
    RestApiErgoClient.create(
            "http://213.239.193.208:9052/", // use your node or a public node here
            networkType,
            "",
            RestApiErgoClient.getDefaultExplorerUrl(networkType)
    ).execute(ctx -> {
        ErgoTreeContract contract = recipient.getErgoContract();
        UnsignedTransaction unsignedTransaction = BoxOperations.createForSender(sender)
                .withAmountToSpend(amountToSend)
                .putToContractTxUnsigned(ctx, contract);

        // reduce the transaction for use with ErgoPay
        return ctx.newProverBuilder().build().reduce(unsignedTransaction, 0);
    });
}

How to translate this to Python?

At first we need to declare all used imports. These can be done straightforward by looking at the Java imports:

from org.ergoplatform.appkit import RestApiErgoClient, NetworkType, BoxOperations, Address

Constructing the ErgoClient is also a straightforward copy from the Java code:

network_type = NetworkType.TESTNET
node_client = RestApiErgoClient.create("http://213.239.193.208:9052/", network_type, "",
                                       RestApiErgoClient.getDefaultExplorerUrl(network_type))

To execute code within a BlockchainContext, a lambda function is used within Java:

ergoCliebt.execute(ctx -> {
    // ....
    });

Internally, lambda functions in Java are nothing more than an anonymous class implementing a special interface. So to adapt this construct into Python, we need to define such a class implementing this interface. JPype provides special annotations for this:

Clone this wiki locally