starknet-jvm
starknet-jvm copied to clipboard
Starknet SDK for JVM languages (Java, Kotlin, Scala)
☕ starknet jvm ☕
Starknet SDK for JVM languages:
- Java
- Kotlin
- Scala
- Clojure
- Groovy
Table of contents
- Table of contents
- Installation
- Documentation
- Example usages
- Making synchronous requests
- Making asynchronous requests
- Standard flow examples
- Demo applications
- Android demo
- Java demo
- Reusing http clients
- Development
- Hooks
- Running tests
- Prerequisites
- Regular Tests
- Network Tests
- Ensuring idiomatic Java code
- Building documentation
Installation
Select the latest version from the list and follow installation instructions.
Documentation
Documentation is provided in two formats:
Example usages
Making synchronous requests
import com.swmansion.starknet.account.Account;
import com.swmansion.starknet.account.StandardAccount;
import com.swmansion.starknet.data.types.BlockTag;
import com.swmansion.starknet.data.types.Felt;
import com.swmansion.starknet.provider.Provider;
import com.swmansion.starknet.provider.Request;
import com.swmansion.starknet.provider.rpc.JsonRpcProvider;
public class Main {
public static void main(String[] args) {
// Create a provider for interacting with Starknet
Provider provider = new JsonRpcProvider("https://example-node-url.com/rpc");
// Create an account interface
Felt accountAddress = Felt.fromHex("0x13241455");
Felt privateKey = Felt.fromHex("0x425125");
Account account = new StandardAccount(provider, accountAddress, privateKey);
// Make a request
Felt contractAddress = Felt.fromHex("0x42362362436");
Felt storageKey = Felt.fromHex("0x13241253414");
Request<Felt> request = account.getStorageAt(contractAddress, storageKey, BlockTag.LATEST);
Felt response = request.send();
System.out.println(response);
}
}
Making asynchronous requests
import com.swmansion.starknet.account.Account;
import com.swmansion.starknet.account.StandardAccount;
import com.swmansion.starknet.data.types.BlockTag;
import com.swmansion.starknet.data.types.Felt;
import com.swmansion.starknet.provider.Provider;
import com.swmansion.starknet.provider.Request;
import com.swmansion.starknet.provider.rpc.JsonRpcProvider;
import java.util.concurrent.CompletableFuture;
public class Main {
public static void main(String[] args) {
// Create a provider for interacting with Starknet
Provider provider = new JsonRpcProvider("https://example-node-url.com/rpc");
// Create an account interface
Felt accountAddress = Felt.fromHex("0x13241455");
Felt privateKey = Felt.fromHex("0x425125");
Account account = new StandardAccount(provider, accountAddress, privateKey);
// Make a request
Felt contractAddress = Felt.fromHex("0x42362362436");
Felt storageKey = Felt.fromHex("0x13241253414");
Request<Felt> request = account.getStorageAt(contractAddress, storageKey, BlockTag.LATEST);
CompletableFuture<Felt> response = request.sendAsync();
response.thenAccept(System.out::println);
}
}
Standard flow examples
- Deploying account
- Invoking contract: Transferring ETH
- Calling contract: Fetching ETH balance
- Declaring Cairo 1/2 contract
Demo applications
These demo apps can be used with any Starknet RPC node, including devnet. They are intended for demonstration/testing purposes only.
Android demo
Java demo
Reusing http clients
Make sure you don't create a new provider every time you want to use one. Instead, you should reuse existing instance. This way you reuse connections and thread pools.
✅ Do:
var provider = new JsonRpcProvider("https://example-node-url.com/rpc");
var account1 = new StandardAccount(provider, accountAddress1, privateKey1);
var account2 = new StandardAccount(provider, accountAddress2, privateKey2);
❌ Don't:
var provider1 = new JsonRpcProvider("https://example-node-url.com/rpc");
var account1 = new StandardAccount(provider1, accountAddress1, privateKey1);
var provider2 = new JsonRpcProvider("https://example-node-url.com/rpc");
var account2 = new StandardAccount(provider2, accountAddress2, privateKey2);
Development
Hooks
Run
./gradlew installKotlinterPrePushHook
Running tests
Prerequisites
starknet-devnet-rs- Since it has yet to be released, you will need to build it manually and set
DEVNET_PATHenvironment variable that points to a binary:DEVNET_PATH=/path/to/starknet-devnet-rs/target/release/starknet-devnet - You can do so by using environment variables in your system or IDE, or by sourcing an
.envfile. Refer to the example config found in test_variables.env.example.
- Since it has yet to be released, you will need to build it manually and set
starknet-foundry- providessncastcliasdfversion manager andasdf scarbplugin
Regular Tests
Use the following command to run tests:
./gradlew :lib:test
Network Tests
Running tests on networks requires a valid configuration. It can be set using environment variables in your system or IDE, or by sourcing an .env file.
Refer to the example config found in test_variables.env.example.
To select the network, please set the NETWORK_TEST_NETWORK_NAME environment variable. Currenty, the allowed options are:
SEPOLIA_TESTNETSEPOLIA_INTEGRATION
Note: The transition of network tests from GOERLI to SEPOLIA networks results in a current limitation of v3 tests.
To properly configure your network, ensure the following variables are set with the NETWORK_NAME_ prefix:
RPC_URL- url of your RPC nodeACCOUNT_ADDRESSandPRIVATE_KEY- address and private key of your account
Additionally, you can also set:
CONST_NONCE_ACCOUNT_ADDRESSandCONST_NONCE_PRIVATE_KEY- address and private key exclusively for non-gas network tests, preventing potential inconsistencies (sometimes,getNoncemay report higher nonce than expected). Recommended for reliable non-gas testing. These default toACCOUNT_ADDRESSandPRIVATE_KEYif not set.ACCOUNT_CAIRO_VERSION- Cairo version of theACCOUNT_ADDRESSandCONST_NONCE_ACCOUNT_ADDRESSaccounts. Defaults to0.
Network tests are disabled by default. To enable them, you can set the environment variable:
NETWORK_TEST_MODE=non_gas
Some network tests require gas and are disabled by default. If you want to run them as well, you can set:
NETWORK_TEST_MODE=all
⚠️ WARNING ⚠️ Please be aware that in that case your account address must have a pre-existing balance as these tests will consume some funds.
Alternatively, you can use flag to specify whether to run network and gas tests:
./gradlew :lib:test -PnetworkTestMode=non_gas
./gradlew :lib:test -PnetworkTestMode=all
Flag takes precendece over the environment variable if both are set.
Ensuring idiomatic Java code
We want this library to be used by both kotlin & java users. In order to ensure a nice API for java always follow those rules:
- When using file level functions use
@file:JvmName(NAME)to ensure a nice name withoutKtsuffix. - When using a companion object mark every property/function with
@JvmStatic. This way they are accessible as static from the class. Without itClass.INSTANCEwould have to be used. - When defining an immutable constant use
@field:JvmField. This makes them static properties without getters/setters in java. - If you are not sure how something would work in java just create a new java class, import your code and check yourself.
- Avoid using default arguments. It is better to overload a function and specify defaults there.
Building documentation
Documentation is written in Kdoc format and markdown and is generated using Dokka. Execute
following commands from /lib to build docs.
./gradlew dokkaHtmlto build kotlin format docs./gradlew dokkaHtmlJavato build java format docs
Generated documentation can be found in their respective folders inside /build/dokka.