Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Requirements for an independent kotlin client #2

Closed
jillesvangurp opened this issue Jun 7, 2019 · 4 comments
Closed

Requirements for an independent kotlin client #2

jillesvangurp opened this issue Jun 7, 2019 · 4 comments

Comments

@jillesvangurp
Copy link
Owner

jillesvangurp commented Jun 7, 2019

Introduction

This issue is intended to get feedback on requirements for a proper Kotlin client for stellar. The current incarnation depends on the Java client. While this works, it comes with a few limitations.

Additionally, other than it being convenient because its there, there is no technical reason to use it since Kotlin can act as a drop in replacement for Java on both android and the JVM and has the potential to also be of use beyond that through Kotlin multi platform builds that utilize the jvm, native (Android/IOS/x86/wasm), and kotlin-js compilers.

So the goal would be to build a pure Kotlin client that can serve multiple platforms, including those currently served by the java client, and do so using all the nice features that Kotlin has including things like data classes, co-routines, etc.

Motivation

Both the Android and JVM backend world are gravitating towards using Kotlin as a primary language. Google just endorsed Kotlin as the primary language for Android and the Spring project is now also recommending Kotlin as the primary language if you are using e.g. Spring Boot 2.x, which has many Kotlin specific extensions and is designed to be Kotlin friendly.

The current java sdk is stuck at using Android compatible Java, which means a lot of the modern Java features are not usable (lambda's, streams, type inference, etc.) because they are not supported in Android. Additionally, while quite robust and functional, the Java sdk is a bit lacking in terms of API, internal design and feature set.

Plan and architecture

Structure the client as a kotlin multi platform project with:

  • A platform neutral module with most of the business logic, mashalling, etc. We can utilize things like KTor to abstract the networking; make use of co-routines to support asynchronous calls to horizon; and potentially investigate the use of e.g. kotlinx.serialization for XDR marshalling.
  • JVM platform module that uses the okhttpclient implementation of ktor. This should target both Android and the JVM. Where applicable we can provide Java friendly Kotlin Apis annotated with e.g. @JvmStatic to ensure this is usable from both Kotlin and Java.
  • Android/IOS native module. If we can do one, we can do the other as well.
  • Kotlin-js module - this would allow it to be used in Kotlin frontend projects.
  • A WASM module to be able to run the client in e.g. a browser or via e.g. WASI in serverless environments.

The last two modules would be experimental initially as support for this in Kotlin is experimental still. However, I'm interested in running this in a browser and would like the project to be ready for this at least.

The intention with both Kotlin-js and wasm would be to support the emerging Kotlin frontend frameworks out there and not necessarily act as a replacement for the current js/typescript projects. However, there is an obvious potential for some code sharing here for e.g. crypto and marshalling.

For marshalling, the most obvious thing to do would be to add a kotlin generator to the xdrgen project.

For crypto, there may be some question marks as there may be a lack of cross platform kotlin crypto code. The fallback solution would be to use platform specific libraries similar to what is used in the current SDKs and provide a facade for those in the Kotlin neutral module.

Functionality

  • support all the horizon operations
  • provide both synchronous and asynchronous apis (via co-routines)
  • provide marshaling to/from xdr
  • provide primitives for doing token math and converting between long values that Stellar stores and the doubles that users of an API would need to present end to users.
  • make sure the client stays aligned with horizon and the xdrs in stellar-core
  • make it easy to use the client against any stellar network (public, testnet, and standalone).
  • provide validation, error handling, etc. in a Kotlin friendly way so that users don't have to reinvent things like retry strategies, figuring out different errors that may be expected, etc.
  • make everything dependency injection friendly (i.e. constructor injected arguments, no magic numbers/hard coded config).

Some of the above is already provided by the current kotlin client and this just would be about preserving what we have.

Feedback

This project would obviously be a bit bigger effort for me personally and I would like to get some feedback specifically around the following topics:

  • Do you agree with the technical approach here?
  • Would you use this and if so which of the platforms are you most interested in?
  • Can you recommend specific things in Kotlin I should look at regarding this. Particularly, solutions for crypto and marshaling?

If you have detailed requirements, feel free to file separate issues or just leave a comment on this one.

If you want to help out, awesome. Please reach out and we'll discuss. Before creating bigger pull requests, please discuss with me first so we can avoid doing double work, conflicts, etc.

@Synesso
Copy link
Contributor

Synesso commented Jun 8, 2019

I think this is a great idea. Kotlin is certainly the future of JVM programming in a way that all the previous LOTJ could never achieve, so I think there's a place for a native Kotlin SDK.

For marshalling, it might be an idea to look into wire. It has a Kotlin generator and integrates with Moshi. I'm not sure exactly how, as the doc is unclear, but I am pretty sure you can get nicely generated Kotlin sources and gRPC happening.

For XDR, I too thought that modifying the xdrgen project was the easiest way forward. Actually, it was the most painful thing and in the end only 95% worked. It was far simpler to build a small library that did the serde manually. It was very easy to write and having high test coverage ensured that it was correct.

@jillesvangurp
Copy link
Owner Author

@Synesso ideally I'd like to use kotlinx.serialization for json.

Like ktor, it has a platform neutral part and platform specific implementations based on third party stuff like jackson or gson on the jvm, the browser's built in JSON.parse on browsers and whatever people use on android native and IOS.

I may end up converting the existing Java model classes to kotlin and annotating them. That sounds like it's the most straightforward path.

I'd be interested in learning more about your solution for xdr. I've done some small pull requests against xdrgen and I agree it is a bit meh (a good reminder why I never liked ruby). I also considered writing my own thing but am a bit hesitant reinventing that wheel unless I have to. One of the goals for me would be to generate nice kotlin data classes inheriting from sealed classes and implementing interfaces. The current generated java code lacks these abstractions.

@ire-and-curses
Copy link

Regarding XDR: Have you seen https://github.com/xdrpp/stc/tree/master/cmd/goxdr? @stanford-scs wrote it. We are looking at moving to this internally for the Go SDK. I don't know how easy it would be to add Kotlin as another output, but worth a look.

@jillesvangurp
Copy link
Owner Author

Due to the shut down of the Inbot platform, I can't continue to work on this as planned.

So, closing this ticket for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants