Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
mcsherrylabs committed Oct 8, 2020
2 parents 0472abb + d4c95fa commit a7b06fd
Show file tree
Hide file tree
Showing 58 changed files with 4,966 additions and 3 deletions.
40 changes: 40 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Publish to Maven

env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONA_USER: ${{ secrets.SONA_USER }}
SONA_PASS: ${{ secrets.SONA_PASS }}

on:
push:
tags:
- 'v*'

jobs:
package:
runs-on: ubuntu-latest
steps:
- name: Configure GPG Key
run: |
mkdir -p ~/.gnupg/
printf "$GPG_SIGNING_KEY" | base64 --decode > ~/.gnupg/private.key
gpg --import --no-tty --batch --yes ~/.gnupg/private.key
env:
GPG_SIGNING_KEY: ${{ secrets.GPG_SIGNING_KEY }}
- uses: actions/checkout@v2
- name: Package
uses: actions/[email protected]
with:
java-version: '11.0.8'
- run: sbt publishSigned sonatypeRelease
- name: Package Command Line Jar
uses: actions/[email protected]
with:
java-version: '11.0.8'
- run: sbt assembly
- name: Upload Command Line Jar
uses: actions/upload-artifact@v2
with:
name: psg-cardano-wallet-api-assembly
path: target/scala-2.13/psg-cardano-wallet-api-assembly*.jar

40 changes: 40 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Clean, build, test, coverage

env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

on:
push:
branches:
- master
- develop
pull_request:
branches:
- master
- develop

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run tests
uses: actions/[email protected]
with:
java-version: '11.0.8'
- run: sbt coverage test it:test coverageReport
env:
BASE_URL: ${{ secrets.BASE_URL }}
CARDANO_API_WALLET_1_PASSPHRASE: ${{ secrets.CARDANO_API_WALLET_1_PASSPHRASE }}
CARDANO_API_WALLET_1_MNEMONIC: ${{ secrets.CARDANO_API_WALLET_1_MNEMONIC }}
CARDANO_API_WALLET_2_MNEMONIC: ${{ secrets.CARDANO_API_WALLET_2_MNEMONIC }}
CARDANO_API_WALLET_3_MNEMONIC: ${{ secrets.CARDANO_API_WALLET_3_MNEMONIC }}
CARDANO_API_WALLET_3_MNEMONIC_SECONDARY: ${{ secrets.CARDANO_API_WALLET_3_MNEMONIC_SECONDARY }}
CARDANO_API_WALLET_3_PASSPHRASE: ${{ secrets.CARDANO_API_WALLET_3_PASSPHRASE }}

- name: Archive code coverage results
uses: actions/upload-artifact@v2
with:
name: code-coverage-report
path: target/scala-2.13/scoverage-report

2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.idea
target
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright [yyyy] [name of copyright owner]
Copyright 2020 iog-psg

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
147 changes: 145 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,145 @@
# psg-cardano-wallet-api
Scala client to the Cardano wallet REST API
# PSG Cardano Wallet API

_For consultancy services email [[email protected]](mailto:[email protected])_
### Scala and Java client for the Cardano Wallet API

The Cardano node exposes a [REST like API](https://github.com/input-output-hk/cardano-wallet)
allowing clients to perform a variety of tasks including
- creating or restoring a wallet
- submitting a transaction with or without [metadata](https://github.com/input-output-hk/cardano-wallet/wiki/TxMetadata)
- checking on the status of the node
- listing transactions
- listing wallets

The full list of capabilities can be found [here](https://input-output-hk.github.io/cardano-wallet/api/edge/).

This artefact wraps calls to that API to make them easily accessible to Java or Scala developers.

It also provides an executable jar to provide rudimentary command line access.


- [Building](#building)
- [Usage](#usage)
- [scala](#usagescala)
- [java](#usagejava)
- [Command line executable jar](#cmdline)
- [Examples](#examples)
- [Issues](#issues)


### <a name="building"></a> Building

This is an `sbt` project, so the usual `sbt` commands apply.

Clone the [repository](https://github.com/input-output-hk/psg-cardano-wallet-api)

To build and publish the project to your local repository use

`sbt publish`

To build the command line executable jar use

`sbt assembly`

To build the command line executable jar skipping tests, use

`sbt 'set test in assembly := {}' assembly`

This will create a jar in the `target/scala-2.13` folder.

#### Implementation

The jar is part of an Akka streaming ecosystem and unsurprisingly uses [Akka Http](https://doc.akka.io/docs/akka-http/current/introduction.html) to make the http requests,
it also uses [circe](https://circe.github.io/circe/) to marshal and unmarshal the json.

### <a name="usage"></a>Usage

The jar is published in Maven Central, the command line executable jar can be downloaded from the releases section
of the [github repository](https://github.com/input-output-hk/psg-cardano-wallet-api)


Before you can use this API you need a cardano wallet backend to contact, you can set one up following the instructions
[here](https://github.com/input-output-hk/cardano-wallet). The docker setup is recommended.

Alternatively, for 'tire kicking' purposes you may try `http://cardano-wallet-testnet.iog.solutions:8090/v2/`

#### <a name="usagescala"></a>Scala

Add the library to your dependencies

`libraryDependencies += "iog.psg" %% "psg-cardano-wallet-api" % "0.2.0"`

The api calls return a HttpRequest set up to the correct url and a mapper to take the entity result and
map it from Json to the corresponding case classes. Using `networkInfo` as an example...

```
import iog.psg.cardano.CardanoApi.CardanoApiOps._
import iog.psg.cardano.CardanoApi._
implicit val as = ActorSystem("MyActorSystem")
val baseUri = "http://localhost:8090/v2/"
import as.dispatcher
val api = new CardanoApi(baseUri)
val networkInfoF: Future[CardanoApiResponse[NetworkInfo]] =
api.networkInfo.toFuture.execute
val networkInfo: CardanoApiResponse[NetworkInfo] =
api.networkInfo.toFuture.executeBlocking
networkInfo match {
case Left(ErrorMessage(message, code)) => //do something
case Right(netInfo: NetworkInfo) => // good!
}
```

#### <a name="usagejava"></a>Java

First, add the library to your dependencies,
```
<dependency>
<groupId>iog.psg</groupId>
<artifactId>psg-cardano-wallet-api_2.13</artifactId>
<version>0.2.0</version>
</dependency>
```

Then, using `getWallet` as an example...

```
import iog.psg.cardano.jpi.*;
ActorSystem as = ActorSystem.create();
ExecutorService es = Executors.newFixedThreadPool(10);
CardanoApiBuilder builder =
CardanoApiBuilder.create("http://localhost:8090/v2/")
.withActorSystem(as)
.withExecutorService(es);
CardanoApi api = builder.build();
String walletId = "<PUT WALLET ID HERE>";
CardanoApiCodec.Wallet wallet =
api.getWallet(walletId).toCompletableFuture().get();
```

#### <a name="cmdline"></a>Command Line

To see the usage instructions, use

`java -jar psg-cardano-wallet-api-assembly-x.x.x-SNAPSHOT.jar`

For example, to see the [network information](https://input-output-hk.github.io/cardano-wallet/api/edge/#tag/Network) use

`java -jar psg-cardano-wallet-api-assembly-x.x.x-SNAPSHOT.jar -baseUrl http://localhost:8090/v2/ -netInfo`

#### <a name="examples"></a> Examples

The best place to find working examples is in the [test](https://github.com/input-output-hk/psg-cardano-wallet-api/tree/develop/src/test) folder

#### <a name="issues"></a> Issues

This release does *not* cover the entire cardano-wallet API, it focuses on getting the shelley core functionality into the hands of developers, if you need another call covered please log
an [issue (or make a PR!)](https://github.com/input-output-hk/psg-cardano-wallet-api/issues)
54 changes: 54 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
val akkaVersion = "2.6.8"
val akkaHttpVersion = "10.2.0"
val akkaHttpCirce = "1.31.0"
val circeVersion = "0.13.0"
val scalaTestVersion = "3.1.2"
val commonsCodecVersion = "1.15"

lazy val rootProject = (project in file("."))
.configs(IntegrationTest)
.settings(
Defaults.itSettings,
IntegrationTest / dependencyClasspath := (IntegrationTest / dependencyClasspath).value ++ (Test / exportedProducts).value,
name:= "psg-cardano-wallet-api",
scalaVersion := "2.13.3",
organization := "solutions.iog",
homepage := Some(url("https://github.com/input-output-hk/psg-cardano-wallet-api")),
scmInfo := Some(ScmInfo(url("https://github.com/input-output-hk/psg-cardano-wallet-api"), "scm:[email protected]:input-output-hk/psg-cardano-wallet-api.git")),
developers := List(
Developer("mcsherrylabs", "Alan McSherry", "[email protected]", url("https://github.com/mcsherrylabs")),
Developer("maciejbak85", "Maciej Bak", "[email protected]", url("https://github.com/maciejbak85"))
),
publishMavenStyle := true,
licenses := Seq("APL2" -> url("https://www.apache.org/licenses/LICENSE-2.0.txt")),
description := "A java/scala wrapper for the cardano wallet backend API",
usePgpKeyHex("75E12F006A3F08C757EE8343927AE95EEEF4A02F"),
publishTo := Some {
// publish to the sonatype repository
val sonaUrl = "https://oss.sonatype.org/"
if (isSnapshot.value)
"snapshots" at sonaUrl + "content/repositories/snapshots"
else
"releases" at sonaUrl + "service/local/staging/deploy/maven2"
},
credentials += Credentials("Sonatype Nexus Repository Manager",
"oss.sonatype.org",
sys.env.getOrElse("SONA_USER", ""),
sys.env.getOrElse("SONA_PASS", "")),
dynverSonatypeSnapshots in ThisBuild := true,
javacOptions ++= Seq("-source", "1.8", "-target", "1.8"),
scalacOptions ++= Seq("-unchecked", "-deprecation", "-Ymacro-annotations"),
parallelExecution in Test := true,
parallelExecution in IntegrationTest := false,
libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-http-spray-json" % akkaHttpVersion,
"com.typesafe.akka" %% "akka-stream" % akkaVersion,
"com.typesafe.akka" %% "akka-http" % akkaHttpVersion,
"com.typesafe.akka" %% "akka-actor-typed" % akkaVersion,
"com.typesafe.akka" %% "akka-stream" % akkaVersion,
"io.circe" %% "circe-generic-extras" % circeVersion,
"de.heikoseeberger" %% "akka-http-circe" % akkaHttpCirce,
"commons-codec" % "commons-codec" % commonsCodecVersion,
"org.scalatest" %% "scalatest" % scalaTestVersion % "it, test",
)
)
8 changes: 8 additions & 0 deletions cmdline.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash

VER=0.1.3-SNAPSHOT
#BASE_URL="http://cardano-wallet-testnet.iog.solutions:8090/v2/"
#BASE_URL="http://localhost:8090/v2/"

#run sbt assembly to create this jar
exec java -jar target/scala-2.13/psg-cardano-wallet-api-assembly-${VER}.jar -baseUrl ${BASE_URL} "$@"
1 change: 1 addition & 0 deletions project/build.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sbt.version=1.3.13
9 changes: 9 additions & 0 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.15.0")

addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.6.1")

// sbt-sonatype plugin used to publish artifact to maven central via sonatype nexus
// sbt-pgp plugin used to sign the artifcat with pgp keys
addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.4")
addSbtPlugin("com.jsuereth" % "sbt-pgp" % "2.0.1")
addSbtPlugin("com.dwijnand" % "sbt-dynver" % "4.1.1")
75 changes: 75 additions & 0 deletions src/it/java/iog/psg/cardano/TestMain.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package iog.psg.cardano;

import akka.actor.ActorSystem;
import iog.psg.cardano.jpi.CardanoApi;
import iog.psg.cardano.jpi.*;
import scala.Enumeration;

import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestMain {

public static void main(String[] args) throws CardanoApiException, ExecutionException, InterruptedException {

try {
ActorSystem as = ActorSystem.create();
ExecutorService es = Executors.newFixedThreadPool(10);
CardanoApiBuilder builder =
CardanoApiBuilder.create("http://localhost:8090/v2/")
.withActorSystem(as)
.withExecutorService(es);

CardanoApi api = builder.build();
String passphrase = "password10";
String menmString = "receive post siren monkey mistake morning teach section mention rural idea say offer number ribbon toward rigid pluck begin ticket auto";
List<String> menmLst = Arrays.asList(menmString.split(" "));
String walletId = "b63eacb4c89bd942cacfe0d3ed47459bbf0ce5c9";


CardanoApiCodec.Wallet wallet = null;
try {
wallet =
api.getWallet(walletId).toCompletableFuture().get();
} catch(Exception e) {
wallet = api.createRestore("cardanoapimainspec", passphrase, menmLst, 10).toCompletableFuture().get();
}

CardanoApiCodec.WalletAddressId unusedAddr = api.listAddresses(wallet.id(), AddressFilter.UNUSED).toCompletableFuture().get().get(0);

Enumeration.Value lovelace = CardanoApiCodec.Units$.MODULE$.lovelace();
Map<Long, String> meta = new HashMap();
String l = Long.toString(Long.MAX_VALUE);
meta.put(Long.MAX_VALUE, "hello world");

//9223372036854775807
//meta.put(l, "0123456789012345678901234567890123456789012345678901234567890123");

List<CardanoApiCodec.Payment> pays =
Arrays.asList(
new CardanoApiCodec.Payment(unusedAddr.id(),
new CardanoApiCodec.QuantityUnit(1000000, lovelace)
)
);
CardanoApiCodec.CreateTransactionResponse resp =
api.createTransaction(
wallet.id(),
passphrase,
pays,
MetadataBuilder.withMap(meta),
"self").toCompletableFuture().get();
System.out.println(resp.status().toString());
System.out.println(resp.id());
System.out.println(resp.metadata());

//executeHelper.execute(req);
} catch (Exception e) {
System.out.println(e.toString());
} finally {
System.exit(9);
}

}
}
Loading

0 comments on commit a7b06fd

Please sign in to comment.