Code Monkey home page Code Monkey logo

substrate-client-kotlin's Introduction

Kotlin Substrate Client

License

substrate-client-kotlin is client library to interact with a substrate-based chain. It uses the API available from the RPC endpoint only (no sidecar). As of today it provides the following functionality:

  • compatible with substrate 2.0
  • ed25519 wallet creation
  • get account info (balance)
  • sign extrinsic and send (immortal era)
  • estimate fee

what is currently not supported

  • sr25519 wallet
  • mortal era extrinsic

Using the library

  1. Add the JitPack repository.
allprojects {
  repositories {
    ...
    maven { url 'https://jitpack.io' }
  }
}
  1. Add the substrate-client dependency
dependencies {
        implementation 'com.github.NodleCode:substrate-client-kotlin:1.0'
}

Running the tests over custom rpc endpoints

The library comes with a set of JUnit Test to ensure that the api
provided by this library works properly

In order to test that this library works over your own substrate rpc
endpoints, you need to provide the chains configuration that will be
used by the tests.

Simply create a file in

substrate-client/src/test/resources/rpc-test.config

This file must be a CSV (without header) and must contain 3 columns per lines:

  • rpc endpoint (e.g. wss://rpc.polkadot.io)
  • alice wallet mnemonic
  • bob wallet mnemonic

Alice and Bob wallet must be provisioned with enough token to be able to perform the test and pay the fees. When testing sending transaction, the test will always send token from the wallet with the most token.

Here is an example of such file (wallets and rpc doesn't exists):

wss://mainnet.substrate-chain.io,smoke key grief belt gather absurd open attend keep flip hollow popular,total arch interest inmate book cigar primary long mixture party practice old
wss://testnet.substrate-chain.io,pumpkin poem tuition scatter elder moral hockey valley health head joke stem,pupil opinion unhappy nerve adult lunch dolphin famous angry draw soap like

You can then run the tests with gradle:

./gradlew test

The test report will be generated in substrate-client/build/reports/test/index.html

Additional Notes

This is a work in progress and comes with no warranty. contribution are welcome. If you have any question, ideas or if you found a bug, please open an issue!

substrate-client-kotlin's People

Contributors

marlinski avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

substrate-client-kotlin's Issues

Use in Java - wallet1.getAccountInfo(provider) cannot find symbol method getAccountInfo(SubstrateProvider)

Similar to #5 get compilation for wallet1.getAccountInfo(provider)

package bcd.java;

import io.nodle.substratesdk.account.InvalidAccount;
import io.nodle.substratesdk.rpc.SubstrateProvider;
import io.nodle.substratesdk.account.Wallet;
//@Slf4j
public class UsingSubstrateClientKotlin {
    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(UsingSubstrateClientKotlin.class);

    public static void main(String[] args) {
        String rpcUrl = "ws://127.0.0.1:9944";
        var provider = new SubstrateProvider(rpcUrl);
        var specVersion = provider.getTransactionVersion().blockingGet();
        log.info("getTransactionVersion specVersion={}", specVersion); //OK

        String mnemonic = "";
        Wallet wallet1 = null;
        try {
            wallet1 = new Wallet(mnemonic);
        } catch (InvalidAccount e) {
            e.printStackTrace();
        }
        var balance1 = wallet1.getAccountInfo(provider).blockingGet();
    }
}

and get error

bcd-java/src/main/java/bcd/java/UsingSubstrateClientKotlin.java:34: error: cannot find symbol
        var balance1 = wallet1.getAccountInfo(provider).blockingGet();
                              ^
  symbol:   method getAccountInfo(SubstrateProvider)
  location: variable wallet1 of type Wallet

v1.0.1 Release for additional use in Java

To consume small changes for #5 #6 I had to fork and release as

https://github.com/blockchain-driver/substrate-client/releases/tag/v1.0.1

https://jitpack.io/#blockchain-driver/substrate-client-kotlin

Because of need to release I had to change groupname for jitpack, so changes are not all easily mergeable

master is ready for merge https://github.com/blockchain-driver/substrate-client
bcdbuild is not https://github.com/blockchain-driver/substrate-client/tree/bcdbuild


Please release next version with larger number, e.g. 1.1
and define version for modules see
blockchain-driver@e49c821

allprojects {
    //group 'com.github.blockchain-driver'
    //artifact name is folder name by default
    version '1.0.1'
}

as version 1.0 released before in not defined in build.gradle files,
but likely is default of some util, e.g. gversion.

test FAILED While trying to create object of class class java.lang.String could not find constructor with arguments matching (type-wise) the ones given in parameters.

when running test using substrate-client/src/test/resources/rpc-test.config like

wss://127.0.0.1:9944,smoke key grief belt gather absurd open attend keep flip hollow popular,total arch interest inmate book cigar primary long mixture party practice old

that is locally running polkadot ./polkadot --dev -dPolkadotData

2021-09-10 14:30:22 Running in --dev mode, RPC CORS has been disabled.    
2021-09-10 14:30:22 Parity Polkadot    
2021-09-10 14:30:22 ✌️  version 0.9.7-5d35bac74-x86_64-macos    
2021-09-10 14:30:22 ❤️  by Parity Technologies <[email protected]>, 2017-2021    
2021-09-10 14:30:22 📋 Chain specification: Development    
2021-09-10 14:30:22 🏷 Node name: exuberant-doctor-0049    
2021-09-10 14:30:22 👤 Role: AUTHORITY    
2021-09-10 14:30:22 💾 Database: RocksDb at PolkadotData/chains/dev/db    
2021-09-10 14:30:22 ⛓  Native runtime: polkadot-9070 (parity-polkadot-0.tx7.au0)    
2021-09-10 14:30:23 🏷 Local node identity is: 12D3KooWA49uLBFkphZHBYLi4hcY5DRSXom7d1QjM1CidGPbHLKT    
2021-09-10 14:30:24 📦 Highest known block at #14415    
2021-09-10 14:30:24 〽️ Prometheus server started at 127.0.0.1:9615    
2021-09-10 14:30:24 Listening for new connections on 127.0.0.1:9944.    

and get Exception

> Task :substrate-client:test FAILED

While trying to create object of class class java.lang.String could not find constructor with arguments matching (type-wise) the ones given in parameters.
java.lang.IllegalStateException: While trying to create object of class class java.lang.String could not find constructor with arguments matching (type-wise) the ones given in parameters.
	at junitparams.internal.InvokeParameterisedMethod.createObjectOfExpectedTypeBasedOnParams(InvokeParameterisedMethod.java:84)
	at junitparams.internal.InvokeParameterisedMethod.castParamsFromObjects(InvokeParameterisedMethod.java:66)
	at junitparams.internal.InvokeParameterisedMethod.<init>(InvokeParameterisedMethod.java:37)
	at junitparams.internal.ParameterisedTestClassRunner.buildMethodInvoker(ParameterisedTestClassRunner.java:125)
	at junitparams.internal.ParameterisedTestClassRunner.parameterisedMethodInvoker(ParameterisedTestClassRunner.java:118)
	at junitparams.JUnitParamsRunner.methodInvoker(JUnitParamsRunner.java:482)
	at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:273)
	at junitparams.JUnitParamsRunner.runChild(JUnitParamsRunner.java:446)
	at junitparams.JUnitParamsRunner.runChild(JUnitParamsRunner.java:393)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:110)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
	at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62)
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
	at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker$2.run(TestWorker.java:176)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
	at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:133)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:71)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
Caused by: java.lang.NoSuchMethodException: java.lang.String.<init>(java.lang.String, java.lang.String, java.lang.String)
	at java.base/java.lang.Class.getConstructor0(Class.java:3349)
	at java.base/java.lang.Class.getConstructor(Class.java:2151)
	at junitparams.internal.InvokeParameterisedMethod.createObjectOfExpectedTypeBasedOnParams(InvokeParameterisedMethod.java:81)
	... 37 more


io.nodle.substratesdk.TestRpc > classMethod FAILED
    java.lang.IllegalStateException at InvokeParameterisedMethod.java:84
        Caused by: java.lang.NoSuchMethodException at Class.java:3349
6 tests completed, 1 failed
FAILURE: Build failed with an exception.

I have no idea, as no Kotlin expert, other than higher Java version is needed.
Currently using JDK 11

use in Java - error: reference to getMetadata is ambiguous

public static void main(String[] args) {
        String rpcUrl = "wss://127.0.0.1:9944";
        var provider = new SubstrateProvider(rpcUrl);
        var meta = provider.getMetadata().blockingGet();

}

build and get error

 % gradle build

> Task :compileJava FAILED
bcd-java/src/main/java/UsingSubstrateClientKotlin.java:10: error: reference to getMetadata is ambiguous
        var meta = provider.getMetadata().blockingGet();
                           ^
  both method getMetadata() in SubstrateProvider and method getMetadata() in SubstrateProvider match
bcd-java/src/main/java/UsingSubstrateClientKotlin.java:10: error: cannot find symbol
        var meta = provider.getMetadata().blockingGet();
                                         ^
  symbol:   method blockingGet()
  location: class RuntimeMetadata
2 errors

FAILURE: Build failed with an exception.

For sure this should be "call Kotlin from Java" issue, however I have no clue how to solve

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.