Code Monkey home page Code Monkey logo

wavesj's Introduction

Maven Central

WavesJ

A Java library for interacting with the Waves blockchain.

Supports node interaction, offline transaction signing and creating addresses and keys.

Using WavesJ in your project

Use the codes below to add WavesJ as a dependency for your project.

Requirements:
  • JDK 1.8 or above
Maven:
<dependency>
    <groupId>com.wavesplatform</groupId>
    <artifactId>wavesj</artifactId>
    <version>1.3.0</version>
</dependency>
Gradle:
compile group: 'com.wavesplatform', name: 'wavesj', version: '1.3.0'
SBT:
libraryDependencies += "com.wavesplatform" % "wavesj" % "1.3.0"

This library's page at Maven Central

Getting started

Create an account from a private key ('T' for testnet) from random seed phrase:

String seed = Crypto.getRandomSeedPhrase();
PrivateKey privateKey = PrivateKey.fromSeed(seed);
PublicKey publicKey = PublicKey.from(privateKey);
Address address = Address.from(publicKey);

Create a Node and learn a few things about blockchain:

Node node = new Node(Profile.MAINNET);
System.out.println("Current height is " + node.getHeight());
System.out.println("My balance is " + node.getBalance(address));
System.out.println("With 100 confirmations: " + node.getBalance(address, 100));

Send some money to a buddy:

Address buddy = new Address("3N9gDFq8tKFhBDBTQxR3zqvtpXjw5wW3syA");
node.broadcast(TransferTransaction.builder(buddy, Amount.of(1_00000000, Asset.WAVES)).getSignedWith(privateKey));

Set a script on an account. Be careful with the script you pass here, as it may lock the account forever!

Base64String script = node
    .compile("{-# CONTENT_TYPE EXPRESSION #-} sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)")
    .script();
node.broadcast(new SetScriptTransaction(publicKey, script).addProof(privateKey));

Reading transaction info

Same transaction from REST API

Id ethTxId = new Id("CWuFY42te67sLmc5gwt4NxwHmFjVfJdHkKuLyshTwEct");
EthereumTransactionInfo ethInvokeTxInfo = node.getTransactionInfo(ethTxId, EthereumTransactionInfo.class);

EthereumTransaction ethInvokeTx = ethInvokeTxInfo.tx();
EthereumTransaction.Invocation payload = (EthereumTransaction.Invocation) ethInvokeTx.payload();

System.out.println("is ethereum invoke transaction: " + ethInvokeTxInfo.isInvokeTransaction());

System.out.println("type: " + ethInvokeTx.type());
System.out.println("id: " + ethInvokeTx.id().encoded());
System.out.println("fee: " + ethInvokeTx.fee().value());
System.out.println("feeAssetId: " + ethInvokeTx.fee().assetId().encoded());
System.out.println("timestamp: " + ethInvokeTx.timestamp());
System.out.println("version: " + ethInvokeTx.version());
System.out.println("chainId: " + ethInvokeTx.chainId());
System.out.println("bytes: " + ethInvokeTxInfo.getBytes());
System.out.println("sender: " + ethInvokeTx.sender().address().encoded());
System.out.println("senderPublicKey: " + ethInvokeTx.sender().encoded());
System.out.println("height: " + ethInvokeTxInfo.height());
System.out.println("applicationStatus: " + ethInvokeTxInfo.applicationStatus());
System.out.println("payload dApp: " + payload.dApp().encoded());
System.out.println("payload call function: " + payload.function().name());
List<Arg> args = payload.function().args();
System.out.println("payload call function arguments type: " + args.get(0).type());
System.out.println("payload call function arguments value: " + ((StringArg) args.get(0)).value());
DataEntry dataEntry = ethInvokeTxInfo.getStateChanges().data().get(0);
System.out.println("state changes data key: " + dataEntry.key());
System.out.println("state changes data type: " + dataEntry.type().name());
System.out.println("state changes data value: " + ((StringEntry) dataEntry).value());

Broadcasting transactions

Creating accounts (see Getting started for more info about account creation)

PrivateKey alice = createAccountWithBalance(10_00000000);
PrivateKey bob = createAccountWithBalance(10_00000000);

Broadcasting exchange transaction

AssetId assetId = node.waitForTransaction(node.broadcast(
        IssueTransaction.builder("Asset", 1000, 2).getSignedWith(alice)).id(),
        IssueTransactionInfo.class).tx().assetId();

Amount amount = Amount.of(1);
Amount price = Amount.of(100, assetId);
long matcherFee = 300000;
Order buy = Order.builder(OrderType.BUY, amount, price, alice.publicKey()).getSignedWith(alice);
Order sell = Order.builder(OrderType.SELL, amount, price, alice.publicKey()).getSignedWith(bob);

ExchangeTransaction tx = ExchangeTransaction
        .builder(buy, sell, amount.value(), price.value(), matcherFee, matcherFee).getSignedWith(alice);
node.waitForTransaction(node.broadcast(tx).id());

TransactionInfo commonInfo = node.getTransactionInfo(tx.id());
ExchangeTransactionInfo txInfo = node.getTransactionInfo(tx.id(), ExchangeTransactionInfo.class);

Working with dApp

Creating accounts (see Getting started for more info about account creation)

PrivateKey alice = createAccountWithBalance(10_00000000);
PrivateKey bob = createAccountWithBalance(10_00000000);

Broadcasting issue transaction

AssetId assetId = node.waitForTransaction(node.broadcast(
        IssueTransaction.builder("Asset", 1000, 2).getSignedWith(alice)).id(),
        IssueTransactionInfo.class).tx().assetId();

Compiling and broadcasting RIDE script

Base64String script = node.compileScript(
        "{-# STDLIB_VERSION 5 #-}\n" +
        "{-# CONTENT_TYPE DAPP #-}\n" +
        "{-# SCRIPT_TYPE ACCOUNT #-}\n" +
        "@Callable(inv)\n" +
        "func call(bv: ByteVector, b: Boolean, int: Int, str: String, list: List[Int]) = {\n" +
        "  let asset = Issue(\"Asset\", \"\", 1, 0, true)\n" +
        "  let assetId = asset.calculateAssetId()\n" +
        "  let lease = Lease(inv.caller, 7)\n" +
        "  let leaseId = lease.calculateLeaseId()\n" +
        "  [\n" +
        "    BinaryEntry(\"bin\", assetId),\n" +
        "    BooleanEntry(\"bool\", true),\n" +
        "    IntegerEntry(\"int\", 100500),\n" +
        "    StringEntry(\"assetId\", assetId.toBase58String()),\n" +
        "    StringEntry(\"leaseId\", leaseId.toBase58String()),\n" +
        "    StringEntry(\"del\", \"\"),\n" +
        "    DeleteEntry(\"del\"),\n" +
        "    asset,\n" +
        "    SponsorFee(assetId, 1),\n" +
        "    Reissue(assetId, 4, false),\n" +
        "    Burn(assetId, 3),\n" +
        "    ScriptTransfer(inv.caller, 2, assetId),\n" +
        "    lease,\n" +
        "    LeaseCancel(lease.calculateLeaseId())\n" +
        "  ]\n" +
        "}").script();
node.waitForTransaction(node.broadcast(
        SetScriptTransaction.builder(script).getSignedWith(bob)).id());

Calling dApp

InvokeScriptTransaction tx = InvokeScriptTransaction
        .builder(bob.address(), Function.as("call",
                BinaryArg.as(alice.address().bytes()),
                BooleanArg.as(true),
                IntegerArg.as(100500),
                StringArg.as(alice.address().toString()),
                ListArg.as(IntegerArg.as(100500))
        )).payments(
                Amount.of(1, assetId),
                Amount.of(2, assetId),
                Amount.of(3, assetId),
                Amount.of(4, assetId),
                Amount.of(5, assetId),
                Amount.of(6, assetId),
                Amount.of(7, assetId),
                Amount.of(8, assetId),
                Amount.of(9, assetId),
                Amount.of(10, assetId)
        ).extraFee(1_00000000)
        .getSignedWith(alice);
node.waitForTransaction(node.broadcast(tx).id());

Receiving invoke script transaction info

TransactionInfo commonInfo = node.getTransactionInfo(tx.id());
InvokeScriptTransactionInfo txInfo = node.getTransactionInfo(tx.id(), InvokeScriptTransactionInfo.class);

wavesj's People

Contributors

alexkof avatar amurdev avatar apsydev avatar atemerev avatar blackturtle123 avatar dependabot[bot] avatar devyatkinalexandr avatar drblast avatar finnoio avatar karasiq avatar kardanovir avatar lystrosaurus avatar msmolyakov avatar nazeim avatar phearnot avatar suadzh avatar tolsi avatar xrtm000 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wavesj's Issues

wavesj is broken on mainnet

I checked maven artifact 0.15.0
OrderDeserializer deserialize:
NPE at
int version = objectMapper.treeToValue(treeNode.get("version"), Integer.class);

Please recall it from maven repo

OrderRejected

public class SpreadBot {
private final long maxOrderSize = 1 * Asset.MILLI; // in priceAsset
private final double halfSpread = 0.01; // 1%
private final long fee = 3 * Asset.MILLI; // in WAVES
private final long period = 60000; // 1 min

private final PrivateKeyAccount account;
private final AssetPair market;
private final Node node, matcher;
private final String matcherKey;

public static SpreadBot mainnetInstance() throws IOException, URISyntaxException {
    String nodeUrl = "https://nodes.wavesplatform.com";
    String matcherUrl = "https://matcher.waves.exchange/matcher";
    return new SpreadBot(
            PrivateKeyAccount.fromPrivateKey(MY_CORRECT_PRIVTE_KEY, Account.MAINNET),
            new AssetPair(Asset.WAVES, "8LQW8f7P5d5PZM7GtZEBgaqRPGSzS3DfPuiXrURJ4AJS"), matcherUrl, nodeUrl, 'W');
}

private SpreadBot(PrivateKeyAccount account, AssetPair market, String matcherUrl, String nodeUrl, char chainId)
        throws IOException, URISyntaxException {
    this.account = account;
    this.market = market;
    this.node = new Node(nodeUrl, chainId);
    this.matcher = new Node(matcherUrl, chainId);
    this.matcherKey = matcher.getMatcherKey();
}

private void cancelOrder(String orderId) throws IOException, InterruptedException {
    String status = matcher.cancelOrder(account, market, orderId);
    System.out.printf("%s %s\n", status, orderId);
}

private String fileOrder(Order.Type type, long price, long amount) throws IOException, InterruptedException {
    long expiration = System.currentTimeMillis() + Math.max(period, 61000); // matcher requires expiration > 1 min
                                                                            // in the future
    Order order = matcher.marketOrder(account, matcherKey, market, type, price, amount, expiration, fee);
    System.out.printf("Filed order %s to %s %d at %d\n", order.getId(), type, amount, price);
    return order.getId().getBase58String();
}

private void round() throws IOException, InterruptedException {
    System.out.println();
    System.out.printf("Current balance  in %s is %d", market.getAmountAsset(),
            node.getBalance(account.getAddress(), market.getAmountAsset()));

    System.out.printf("Current balance  in %s is %d", market.getPriceAsset(),
            node.getBalance(account.getAddress(), market.getPriceAsset()));

    // Cancel all orders filed at our market
    for (Order order : matcher.getOrders(account, market)) {
        if (order.isActive()) {
            cancelOrder(order.getId().getBase58String());
        }
    }

    // Read order book
    OrderBook book = matcher.getOrderBook(market);
    if (book.getBids().size() <= 0) {
        System.out.println("There are no bids, skipping this round");
        return;
    }
    if (book.getAsks().size() <= 0) {
        System.out.println("There are no asks, skipping this round");
        return;
    }

    // Determine buy and sell prices
    long bestBid = book.getBids().get(0).getPrice();
    long bestAsk = book.getAsks().get(0).getPrice();
    System.out.printf("Spread %d : %d\n", bestBid, bestAsk);
    long meanPrice = (bestBid + bestAsk) / 2;
    long buyPrice = (long) (meanPrice * (1 - halfSpread));
    long sellPrice = (long) (meanPrice * (1 + halfSpread));

    // Find out how much we want to buy, and file an order
    long priceAssetAvail = node.getBalance(account.getAddress(), market.getPriceAsset()) - 2 * fee;
    if (priceAssetAvail > 0) {
        long buyOrderSize = Math.min(priceAssetAvail, maxOrderSize) * Asset.TOKEN / buyPrice;
        fileOrder(Order.Type.BUY, buyPrice, buyOrderSize);
    }

    // Same for sell order
    long amountAssetAvail = node.getBalance(account.getAddress(), market.getAmountAsset()) - 2 * fee;
    if (amountAssetAvail > 0) {
        long sellOrderSize = Math.min(amountAssetAvail, maxOrderSize * Asset.TOKEN / sellPrice);
        fileOrder(Order.Type.SELL, sellPrice, sellOrderSize);
    }
}

private class RoundTask extends TimerTask {
    @Override
    public void run() {
        try {
            round();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

public void run() {
    Timer t = new Timer();
    t.schedule(new RoundTask(), 0, period);
}

public static void main(String[] args) throws IOException, URISyntaxException {
    SpreadBot.mainnetInstance().run();
}

}

Any example of Matcher working?

Hello,

I cannot get ** any ** of the WavesJ Matcher tests or examples working on testnet.
I can get them working using WavesCS (.Net).

Even when I change the urls to the following ...

Wave Node : "https://testnode4.wavesnodes.com"
Matcher node : "https://matcher-testnet.wavesnodes.com"

I keep getting OrderRejected Messages. This happens to both calls to matcher.createOrder() and matcher.placeOrder().

Passing null to matcherFeeAssetId in the placeOrder() method seems to bypass the first issue I have (thus we cannot use createOrder()). But the placeOrder() method throws various error messages afterwards. One of which is ... "The order is invalid: SpendAmount should be > 0"

The Account I am using has enough WAVES and I can use the exact same account from WavesCS and the order goes through. So something is wrong with the Java implementation.

I also noticed that the java version has not been updated for quite a while, whereas the WavesCS version has been updated. Is WavesJ still supported?

Best,
Toy

WavesJ dependency issue In Gradle

When trying to add dependency in gradle received such an error

Could not resolve com.wavesplatform:wavesj:1.0.1.
> inconsistent module metadata found. Descriptor: com.wavesplatform:wavesj:1.0.1-SNAPSHOT Errors: bad version: expected='1.0.1' found='1.0.1-SNAPSHOT'

the similar mistake takes place in version 1.0.0

Maven dependency works Ok

Error getting WAVES balance

Hello! I tried to get my WAVES balance, but I got the error: Invalid asset id.
My code:
Node node = new Node(Profile.MAINNET); Address address = new Address("3PPPdfdNBLXPGJJVO5KAUS116JUTr6GvNDd"); node.getAssetBalance(address, AssetId.WAVES);

Maybe I'm doing something wrong. Help me please)

"Invalid cookie header" in logs

With almost any API request, the following warning is printed to stderr:

WARNING: Invalid cookie header: "Set-Cookie: AWSALB=[REDACTED]; Expires=Tue, 13 Feb 2018 12:31:29 GMT; Path=/". Invalid 'expires' attribute: Tue, 13 Feb 2018 12:31:29 GMT

Test flakyness

mvn test fails consistently, when ran locally, but in different flavours, pretty flaky

one error

[ERROR] Tests run: 10, Failures: 1, Errors: 0, Skipped: 1, Time elapsed: 48.809 s <<< FAILURE! - in node.AliasTest
[ERROR] blocksDelay  Time elapsed: 0.63 s  <<< FAILURE!
java.lang.AssertionError: 

Expecting:
  -142863091
to be greater than:
  1000

	at node.BlocksTest.blocksDelay(BlocksTest.java:129)

one other error

[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 33.255 s - in node.LeasingTest
[INFO] 
[INFO] Results:
[INFO] 
[ERROR] Failures: 
[ERROR]   BlockchainTest.rewards:23 
Expecting:
  6
to be between:
  [4, 5]

for the two mvn tests i did from terminal, i moved to running individual tests in IntelliJ

Waves BlockChain NODE URL

Hello Team,

We are using the java library to integrate Waves Wallet in Android Mobile app. The seed is generated but we are not able to get the balance of wallet of specific address due to the Node URL.

Error : java.net.UnknownHostException: my.waves.node: nodename nor servname provided, or not known
Code : Node node = new Node("https://my.waves.node/");

We dont want to setup the node locally, can we make connection to Waves Platform Mainnet with URL.

Could you please let us know what is the "Node URL " that we should use so that we can get wallet balance, perform transactions successfully.

Thank you.

getTransactionsByAddress() throws Exception for InvokeScriptTransaction

GetTransactionByAddress() throws exception for all InvokeScriptTransactions before major upgrade of Wave Node. Refer to -> https://docs.waves.tech/en/keep-in-touch/april#node-api

Old transactions do not have applicationStatus which caused the issue as there is no handler to check if the output json contains applicationStatus or not in InvokeScriptTransaction.

The error is ->
\"n\" is null (through reference chain: java.util.ArrayList[171])

com.fasterxml.jackson.databind.JsonMappingException

I updated the SpreadBot example with actual input values and it does not work.

import com.wavesplatform.wavesj.*;
import com.wavesplatform.wavesj.matcher.Order;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Timer;
import java.util.TimerTask;

public class SpreadBot {
    private final long maxOrderSize = 1 * Asset.MILLI; // in priceAsset
    private final double halfSpread = 0.01; // 1%
    private final long fee = 3 * Asset.MILLI; // in WAVES
    private final long period = 30000; // 1 min

    private final PrivateKeyAccount account;
    private final AssetPair market;
    private final Node node, matcher;
    private final String matcherKey;

    public static SpreadBot testnetInstance() throws IOException, URISyntaxException {
        return new SpreadBot(
                PrivateKeyAccount.fromPrivateKey("CNZvvKknunw4cktcsdKCvyrunbXYa42kC2W46D4kKsGE", Account.TESTNET),
                new AssetPair(Asset.WAVES, "DWgwcZTMhSvnyYCoWLRUXXSH1RSkzThXLJhww9gwkqdn"),
                "https://matcher.testnet.wavesnodes.com/matcher",
                "https://nodes-testnet.wavesnodes.com",  'T');
    }

    private SpreadBot(PrivateKeyAccount account, AssetPair market, String matcherUrl, String nodeUrl, char chainId) throws IOException, URISyntaxException {
        this.account = account;
        this.market = market;
        this.node = new Node(nodeUrl, chainId);
        this.matcher = new Node(matcherUrl, chainId);
        this.matcherKey = matcher.getMatcherKey();
    }

    private void cancelOrder(String orderId) throws IOException, InterruptedException {
        String status = matcher.cancelOrder(account, market, orderId);
        System.out.printf("%s %s\n", status, orderId);
    }

    private String fileOrder(Order.Type type, long price, long amount) throws IOException, InterruptedException {
        long expiration = System.currentTimeMillis() + Math.max(period, 61000); // matcher requires expiration > 1 min in the future
        Order order = matcher.createOrder(account, matcherKey, market, type, price, amount, expiration, fee);
        System.out.printf("Filed order %s to %s %d at %d\n", order.getId(), type, amount, price);
        return order.getId().getBase58String();
    }

    private void round() throws IOException, InterruptedException {
        System.out.println();

        // Cancel all orders filed at our market
        for (Order order: matcher.getOrders(account, market)) {
            if (order.isActive()) {
                cancelOrder(order.getId().getBase58String());
            }
        }

        // Read order book
        OrderBook book = matcher.getOrderBook(market);
        if (book.getBids().size() <= 0) {
            System.out.println("There are no bids, skipping this round");
            return;
        }
        if (book.getAsks().size() <= 0) {
            System.out.println("There are no asks, skipping this round");
            return;
        }

        // Determine buy and sell prices
        long bestBid = book.getBids().get(0).getPrice();
        long bestAsk = book.getAsks().get(0).getPrice();
        System.out.printf("Spread %d : %d\n", bestBid, bestAsk);
        long meanPrice = (bestBid + bestAsk) / 2;
        long buyPrice = (long) (meanPrice * (1 - halfSpread));
        long sellPrice = (long) (meanPrice * (1 + halfSpread));

        // Find out how much we want to buy, and file an order
        long priceAssetAvail = node.getBalance(account.getAddress(), market.getPriceAsset()) - 2 * fee;
        if (priceAssetAvail > 0) {
            long buyOrderSize = Math.min(priceAssetAvail, maxOrderSize) * Asset.TOKEN / buyPrice;
            fileOrder(Order.Type.BUY, buyPrice, buyOrderSize);
        }

        // Same for sell order
        long amountAssetAvail = node.getBalance(account.getAddress(), market.getAmountAsset()) - 2 * fee;
        if (amountAssetAvail > 0) {
            long sellOrderSize = Math.min(amountAssetAvail, maxOrderSize * Asset.TOKEN / sellPrice);
            fileOrder(Order.Type.SELL, sellPrice, sellOrderSize);
        }
    }

    private class RoundTask extends TimerTask {
        @Override public void run() {
            try {
                round();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void run() {
        Timer t = new Timer();
        t.schedule(new RoundTask(), 0, period);
    }

    public static void main(String[] args) throws IOException, URISyntaxException {
        SpreadBot.testnetInstance().run();
    }
}

Exception:

com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: java.util.ArrayList[0])
	at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:394)
	at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:365)
	at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:302)
	at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:245)
	at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:27)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3077)
	at com.wavesplatform.wavesj.Node.parse(Node.java:685)
	at com.wavesplatform.wavesj.Node.getOrders(Node.java:607)
	at com.wavesplatform.wavesj.Node.getOrders(Node.java:593)
	at SpreadBot.round(SpreadBot.java:52)
	at SpreadBot.access$000(SpreadBot.java:9)
	at SpreadBot$RoundTask.run(SpreadBot.java:95)
	at java.util.TimerThread.mainLoop(Timer.java:555)
	at java.util.TimerThread.run(Timer.java:505)
Caused by: java.lang.NullPointerException
	at com.fasterxml.jackson.databind.ObjectMapper.treeToValue(ObjectMapper.java:2745)
	at com.wavesplatform.wavesj.json.deser.OrderDeserializer.deserialize(OrderDeserializer.java:28)
	at com.wavesplatform.wavesj.json.deser.OrderDeserializer.deserialize(OrderDeserializer.java:16)
	at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:286)
	... 12 more

Process finished with exit code 130 (interrupted by signal 2: SIGINT)

Any ideas?

Handle errors if some of multiple ids do not exist

There are methods in the Node API that allow you to request information about several listed entities at once:

  • GET/POST /addresses/balance
  • GET/POST /addresses/data/{address}
  • GET assets/details
  • GET/POST transactions/merkleProof
  • GET/POST transactions/status

Check how WavesJ behaves if some of the requested ids are incorrect for some reason:

  • id is not a correct base58 string
  • entity with this id doesn't exist in blockchain

Example: /assets/details?id=CG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24a&id=DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p

Add handling of such cases. Some of the possible approaches:

  1. throw an exception if at least one id is incorrect
  2. for such methods, return an object with two fields: a list with info for correct ids and a list List<Error> errors with info for incorrect ids.
  3. just skip errors and return only info for correct ids.

Http issue

java.lang.NoSuchFieldError: No static field INSTANCE of type Lorg/apache/http/conn/ssl/AllowAllHostnameVerifier; in class Lorg/apache/http/conn/ssl/AllowAllHostnameVerifier; or its superclasses (declaration of 'org.apache.http.conn.ssl.AllowAllHostnameVerifier' appears in /system/framework/framework.jar:classes2.dex)
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.(SSLConnectionSocketFactory.java:144)
at org.apache.http.impl.client.HttpClientBuilder.build(HttpClientBuilder.java:955)
at com.wavesplatform.wavesj.Node.(Node.java:39)
at com.passinhotv.android.TransferActivity.doTransfer(TransferActivity.java:202)
at com.passinhotv.android.TransferActivity$2.onClick(TransferActivity.java:168)
at android.view.View.performClick(View.java:5273)
at android.view.View$PerformClick.run(View.java:21315)
at android.os.Handler.handleCallback(Handler.java:743)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:150)
at android.app.ActivityThread.main(ActivityThread.java:5659)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:822)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:712)

json转化问题

The problem I found is that the TransferTransactionV2 object generated by the signature will have the parent class attribute. When converting it to json and converting json to TransferTransactionV2 object, it cannot be converted. This is the source of the problem.

Support GRPC API

Add support for GRPC node extension.

NodeGrpc node = new NodeGrpc("grpc.wavesnodes.com", 6870);

The ID returned by the interface 'getTransaction' is not the real ID

The ID of Transaction obtained through 'getTransaction' interface or 'getBlock' interface is not my real ID. How do I get the same ID as returned by waves-node-rest-api?
The sample code is also wrong here.
a9a290bc-1480-4219-bbc1-b6efbfef7db3

Because the two IDs are fundamentally different, transaction cannot be found here.

com.sun.jna.Native.load(Ljava/lang/String;Ljava/lang/Class;)Lcom/sun/jna/Library;

when i used in springboot project it give me this error message, how can i do?,the detail message is:

Exception in thread "main" java.lang.NoSuchMethodError: com.sun.jna.Native.load(Ljava/lang/String;Ljava/lang/Class;)Lcom/sun/jna/Library; at org.whispersystems.curve25519.NativeCurve25519Provider.<clinit>(NativeCurve25519Provider.java:14) at org.whispersystems.curve25519.OpportunisticCurve25519Provider.<init>(OpportunisticCurve25519Provider.java:15) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at java.lang.Class.newInstance(Class.java:442) at org.whispersystems.curve25519.Curve25519.constructClass(Curve25519.java:179) at org.whispersystems.curve25519.Curve25519.constructOpportunisticProvider(Curve25519.java:174) at org.whispersystems.curve25519.Curve25519.getInstance(Curve25519.java:31) at org.whispersystems.curve25519.Curve25519.getInstance(Curve25519.java:23) at com.wavesplatform.crypto.Crypto.<clinit>(Crypto.java:15) at com.wavesplatform.transactions.account.Address.<init>(Address.java:130) at com.wavesplatform.transactions.account.Address.from(Address.java:34) at com.wavesplatform.transactions.account.PublicKey.address(PublicKey.java:92) at com.wavesplatform.transactions.account.PublicKey.address(PublicKey.java:103)

Write javadoc

Write javadoc for all the classes and public methods in WavesJ. Usage examples of the methods are welcome right in the javadoc.

how can i get this jar (com.wavesplatform:protobuf-schemas:pom:1.2.6-SNAPSHOT)

hi ,when i import WavesJ in my project.
like this

      <dependency>
          <groupId>com.wavesplatform</groupId>
          <artifactId>wavesj</artifactId>
          <version>1.0.1</version>
      </dependency>

i found this jar denpendencys in pom.xml like this:

   <dependency>
        <groupId>im.mak</groupId>
        <artifactId>waves-transactions</artifactId>
        <version>1.0.2</version>
    </dependency>
    <dependency>
        <groupId>com.wavesplatform</groupId>
        <artifactId>protobuf-schemas</artifactId>
        <version>1.2.6</version>
    </dependency>
    <dependency> <!-- todo remove after com.wavesplatform.protobuf-schemas 1.2.7 -->
        <groupId>com.google.protobuf</groupId>
        <artifactId>protobuf-java</artifactId>
        <version>3.12.2</version>
    </dependency>

there "protobuf-schemas" version is 1.2.6.
but the waves-transactions pom.xml denpendendy protobuf-schemas version is 1.2.6-SNAPSHOT

    <dependency>
        <groupId>im.mak</groupId>
        <artifactId>waves-crypto</artifactId>
        <version>2.0.1</version>
    </dependency>
    <dependency>
        <groupId>com.wavesplatform</groupId>
        <artifactId>protobuf-schemas</artifactId>
        <version>1.2.6-SNAPSHOT</version>
    </dependency>

i can not find this version 1.2.6-SNAPSHOT in maven repository.

and there is a bug if waves-transactions denpendency protobuf-schemas version 1.2.6.
the class im.mak.waves.transactions.serializers.ProtobufConverter method fromProtobuf
can not find class com.wavesplatform.protobuf.transaction.TransactionOuterClass.Transaction in protobuf-schemas for version 1.2.6.

can anyone fix it?
thanks

Wrong Mass Transfer transaction ID in the "/transactions/address" endpoint

If you request endpoint /transactions/address/ and read MassTransfer transaction in it, the id will differ from the one specified in JSON.

The reason is that in the endpoint in MassTransfer transaction not all recipients are shown, but only the address to which the request was made. By design, the library waves-transactions-java ignores the id field in JSON and calculates ID on its own. So there's no way to correctly calculate the ID.

For example, there's MassTransfer with id FdEdj5SrJV5qNQT6fnewhguXh77BrHc2xAnQArT6maXr:
https://nodes.wavesnodes.com/transactions/address/3PL9HcwsQEDDekmxxhQJGfVMUKBjKH5LbLH/limit/1?after=AiLvMDnj7G3HSnjyWZphWzLAKCqMa5MdQXFFRWsrAEDo

But WavesJ 1.2.3 returns id 3tVzcELheCV4PKBXK7HFeHmKPrWEfLvhYtapr32MSScf:

Node node = new Node(Profile.MAINNET);

Address address = Address.as("3PL9HcwsQEDDekmxxhQJGfVMUKBjKH5LbLH");
Id after = Id.as("AiLvMDnj7G3HSnjyWZphWzLAKCqMa5MdQXFFRWsrAEDo");

List<TransactionInfo> transactionsByAddress = node.getTransactionsByAddress(address, 1, after);

System.out.println( transactionsByAddress.get(0).tx().id() );

Pump README.md

Write a comprehensive description of all features and possible usages:

  • how to generate or import account
  • how to connect to official and own nodes and make requests
  • which endpoints can be requested
  • how to create, sign and send transactions of each type
  • how transaction fields are filled with default values
  • and etc

Matcher: error on request of order history

Error on request of order history:

public List<Order> getOrders(PrivateKeyAccount account) throws IOException {
    return getOrders(account, "/matcher/orderbook/" + Base58.encode(account.getPublicKey()));
}
2019-12-25 13:12:00.84 Cannot construct instance of com.wavesplatform.wavesj.matcher.Order$Type,
 problem: No enum constant com.wavesplatform.wavesj.matcher.Order.Type.LIMIT
 at [Source: (org.apache.http.client.entity.LazyDecompressingInputStream); line: 1, column: 80] 
 (through reference chain: java.util.ArrayList[0]->com.wavesplatform.wavesj.matcher.Order["orderType"])

Need to fix deserialization of OrderHistory item with new field orderType (limit/market).

Q. Can I send wBTC to BTC wallet?

public String transfer(PrivateKeyAccount from, String assetId, String recipient,
                           long amount, long fee, String feeAssetId, String message) throws IOException {
        TransferTransactionV2 tx = Transactions.makeTransferTx(from, recipient, amount, assetId, fee, feeAssetId, message);
        return send(tx);
    }

If make a transfer with WBTC assetId & BTC recipient, Is it possible ?

Getting java.lang.ClassNotFoundException: org.bouncycastle.crypto.Digest

I'm just running the first usage example and getting the error:

Exception in thread "main" java.lang.NoClassDefFoundError: org/bouncycastle/crypto/Digest
at com.hotcoins.bot.WavesJTest.main(WavesJTest.java:10)
Caused by: java.lang.ClassNotFoundException: org.bouncycastle.crypto.Digest
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 1 more

Here is the example from the readme page that I ran:

Create an account from a private key ('T' for testnet):

String seed = "health lazy lens fix dwarf salad breeze myself silly december endless rent faculty report beyond";
PrivateKeyAccount account = PrivateKeyAccount.fromSeed(seed, 0, Account.TESTNET);
byte[] publicKey = account.getPublicKey();
String address = account.getAddress();

Getting genesis block throws NullPointerException

Trying to get the genesis block will cause a NullPointerException because

int version = objectMapper.treeToValue(treeNode.get("version"), Integer.class);
will try to fetch the version even though genesis transactions don't have one.

Steps to reproduce:

Node node = new Node("https://nodes.wavesnodes.com", (byte) 'W');
node.getTransaction("2DVtfgXjpMeFf2PQCqvwxAiaGbiDsxDjSdNQkc5JQ74eWxjWFYgwvqzC4dn7iB1AhuM32WxEiVi1SGijsBtYQwn8");

Result:

Caused by: java.lang.NullPointerException
	at [email protected]/com.fasterxml.jackson.databind.ObjectMapper.treeToValue(ObjectMapper.java:2745)
	at [email protected]/com.wavesplatform.wavesj.json.deser.TransactionDeserializer.deserialize(TransactionDeserializer.java:29)
	at [email protected]/com.wavesplatform.wavesj.json.deser.TransactionDeserializer.deserialize(TransactionDeserializer.java:16)
	at [email protected]/com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:286)
	... 21 more

Token create

I want creat token with wave can i have any instructions ?

WavesJ library throws and error and by result it makes a wrong public key from a seed once in the x-amount of time

This is the error message, 99% from the time is goes good (the same code) and 1% it goes wrong, it doesnt depend on a certain seed or addr, just random.

java.lang.IllegalStateException: attempt to absorb while squeezing
        at org.bouncycastle.crypto.digests.KeccakDigest.absorb(Unknown Source)
        at org.bouncycastle.crypto.digests.KeccakDigest.update(Unknown Source)
        at com.wavesplatform.wavesj.PublicKeyAccount.hash(PublicKeyAccount.java:42)
        at com.wavesplatform.wavesj.PublicKeyAccount.secureHash(PublicKeyAccount.java:49)
        at com.wavesplatform.wavesj.PublicKeyAccount.address(PublicKeyAccount.java:54)
        at com.wavesplatform.wavesj.PublicKeyAccount.<init>(PublicKeyAccount.java:21)
        at com.wavesplatform.wavesj.PrivateKeyAccount.<init>(PrivateKeyAccount.java:207)
        at com.wavesplatform.wavesj.PrivateKeyAccount.fromPrivateKey(PrivateKeyAccount.java:216)
        at com.example.notificationbot.utility.handleFaucets.CreateFaucetsAndHandle.<init>(CreateFaucetsAndHandle.java:40)
        at com.example.notificationbot.Services.TelegramEndPointService.process(TelegramEndPointService.java:361)
        at com.example.notificationbot.Services.TelegramEndPointService$$FastClassBySpringCGLIB$$5e4ff532.invoke(<generated>)
        at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
        at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
        at com.example.notificationbot.Services.TelegramEndPointService$$EnhancerBySpringCGLIB$$3ac225f0.process(<generated>)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.catalina.filters.CorsFilter.handleNonCORS(CorsFilter.java:441)
        at org.apache.catalina.filters.CorsFilter.doFilter(CorsFilter.java:169)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:110)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:108)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:106)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:115)
        at org.springframework.boot.web.support.ErrorPageFilter.access$000(ErrorPageFilter.java:59)
        at org.springframework.boot.web.support.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:90)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:108)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
        at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803)
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

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.