diff --git a/README.md b/README.md index cd386aa..697ef21 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ System.out.println("With 100 confirmations: " + node.getBalance(address, 100)); Send some money to a buddy: ```java Address buddy = new Address("3N9gDFq8tKFhBDBTQxR3zqvtpXjw5wW3syA"); -node.broadcast(TransferTransaction.builder(buddy, Amount.of(1_00000000, Asset.WAVES)).getSignedWith(privateKey)); +node.broadcast(TransferTransaction.builder(buddy, Amount.of(1_00000000, AssetId.WAVES)).getSignedWith(privateKey)); ``` Set a script on an account. Be careful with the script you pass here, as it may lock the account forever! diff --git a/src/main/java/com/wavesplatform/wavesj/Node.java b/src/main/java/com/wavesplatform/wavesj/Node.java index a24aa52..d8fc390 100644 --- a/src/main/java/com/wavesplatform/wavesj/Node.java +++ b/src/main/java/com/wavesplatform/wavesj/Node.java @@ -52,6 +52,9 @@ import static java.util.stream.Collectors.toCollection; import static java.util.stream.Collectors.toList; +/** + * This class represents a node. + */ @SuppressWarnings("unused") public class Node { @@ -126,24 +129,67 @@ public ActivationStatus getActivationStatus() throws IOException, NodeException // ADDRESSES //=============== + /** + * Get a list of account addresses in the node wallet + * + * @return sequences of addresses + * @throws IOException + * @throws NodeException + */ public List
getAddresses() throws IOException, NodeException { return asType(get("/addresses"), TypeRef.ADDRESSES); } + /** + * Get a list addresses in the node wallet by a given range of indices. Max range {from}-{to} is 1000 addresses. + * + * @param fromIndex start index + * @param toIndex end index + * @return sequences of addresses + * @throws IOException + * @throws NodeException + */ public List
getAddresses(int fromIndex, int toIndex) throws IOException, NodeException { return asType(get("/addresses/seq/" + fromIndex + "/" + toIndex), TypeRef.ADDRESSES); } + /** + * Get the regular balance in WAVES at a given address + * + * @param address address base58 encoded + * @return the balance value + * @throws IOException + * @throws NodeException + */ public long getBalance(Address address) throws IOException, NodeException { return asJson(get("/addresses/balance/" + address.toString())) .get("balance").asLong(); } + /** + * Get the minimum regular balance at a given address for {confirmations} blocks back from the current height. + * Max number of confirmations is set by waves.db.max-rollback-depth, 2000 by default + * + * @param address address base58 encoded + * @param confirmations confirmations + * @return the balance value + * @throws IOException + * @throws NodeException + */ public long getBalance(Address address, int confirmations) throws IOException, NodeException { return asJson(get("/addresses/balance/" + address.toString() + "/" + confirmations)) .get("balance").asLong(); } + /** + * Get regular balances for multiple addresses. + * Max number of addresses is set by waves.rest-api.transactions-by-address-limit, 1000 by default + * + * @param addresses sequences of addresses base58 encoded + * @return sequences of Balance objects + * @throws IOException + * @throws NodeException + */ public List getBalances(List
addresses) throws IOException, NodeException { ObjectNode jsonBody = JSON_MAPPER.createObjectNode(); ArrayNode jsonAddresses = jsonBody.putArray("addresses"); @@ -156,6 +202,16 @@ public List getBalances(List
addresses) throws IOException, No .setEntity(body), TypeRef.BALANCES); } + /** + * Get regular balances for multiple addresses. + * Max number of addresses is set by waves.rest-api.transactions-by-address-limit, 1000 by default + * + * @param addresses sequences of addresses base58 encoded + * @param height blockchain height + * @return sequences of Balance objects + * @throws IOException + * @throws NodeException + */ public List getBalances(List
addresses, int height) throws IOException, NodeException { ObjectNode jsonBody = JSON_MAPPER.createObjectNode(); ArrayNode jsonAddresses = jsonBody.putArray("addresses"); @@ -169,14 +225,41 @@ public List getBalances(List
addresses, int height) throws IOE .setEntity(body), TypeRef.BALANCES); } + /** + * Get the available, regular, generating, and effective balance + * + * @see definitions + * @param address address base58 encoded + * @return BalanceDetails object + * @throws IOException + * @throws NodeException + */ public BalanceDetails getBalanceDetails(Address address) throws IOException, NodeException { return asType(get("/addresses/balance/details/" + address.toString()), TypeRef.BALANCE_DETAILS); } + /** + * Read account data entries by given keys or a regular expression. + * Limited by rest-api.data-keys-request-limit, 1000 by default. + * + * @param address address base58 encoded + * @return sequence of DataEntry objects + * @throws IOException + * @throws NodeException + */ public List getData(Address address) throws IOException, NodeException { return asType(get("/addresses/data/" + address.toString()), TypeRef.DATA_ENTRIES); } + /** + * Read account data entries by given keys. Limited by rest-api.data-keys-request-limit, 1000 by default. + * + * @param address address base58 encoded + * @param keys sequence of keys of records + * @return sequence of DataEntry objects + * @throws IOException + * @throws NodeException + */ public List getData(Address address, List keys) throws IOException, NodeException { ObjectNode jsonBody = JSON_MAPPER.createObjectNode(); ArrayNode jsonKeys = jsonBody.putArray("keys"); @@ -188,34 +271,88 @@ public List getData(Address address, List keys) throws IOExce .setEntity(body), TypeRef.DATA_ENTRIES); } - /* - example to javadoc: Pattern.compile("st.+") + /** + * Read account data entries by given keys or a regular expression. + * Limited by rest-api.data-keys-request-limit, 1000 by default. + * + *
Pattern.compile("st.+")
+ * + * @param address address base58 encoded + * @param regex regular expression for filter keys + * @return sequence of DataEntry objects + * @throws IOException + * @throws NodeException */ public List getData(Address address, Pattern regex) throws IOException, NodeException { return asType(get("/addresses/data/" + address.toString()) .addParameter("matches", regex.toString()), TypeRef.DATA_ENTRIES); } + /** + * Read account data entries by a given key + * + * @param address address base58 encoded + * @param key key + * @return DataEntry object + * @throws IOException + * @throws NodeException + */ public DataEntry getData(Address address, String key) throws IOException, NodeException { return asType(get("/addresses/data/" + address.toString() + "/" + key), TypeRef.DATA_ENTRY); } + /** + * Get the effective balance in WAVES at a given address + * + * @param address address base58 encoded + * @return the balance value + * @deprecated {@link #getBalance(Address)} + * @throws IOException + * @throws NodeException + */ @Deprecated public long getEffectiveBalance(Address address) throws IOException, NodeException { return asJson(get("/addresses/effectiveBalance/" + address.toString())) .get("balance").asLong(); } + /** + * Get the minimum effective balance at a given address for {confirmations} blocks from the current height. + * Max number of confirmations is set by waves.db.max-rollback-depth, 2000 by default + * + * @param address address base58 encoded + * @param confirmations confirmations + * @return the balance value + * @deprecated {@link #getBalance(Address, int)} + * @throws IOException + * @throws NodeException + */ @Deprecated public long getEffectiveBalance(Address address, int confirmations) throws IOException, NodeException { return asJson(get("/addresses/effectiveBalance/" + address.toString() + "/" + confirmations)) .get("balance").asLong(); } + /** + * Get an account script or a dApp script with additional info by a given address + * + * @param address address base58 encoded + * @return ScriptInfo object + * @throws IOException + * @throws NodeException + */ public ScriptInfo getScriptInfo(Address address) throws IOException, NodeException { return asType(get("/addresses/scriptInfo/" + address.toString()), TypeRef.SCRIPT_INFO); } + /** + * Get an account script meta + * + * @param address address base58 encoded + * @return ScriptMeta object + * @throws IOException + * @throws NodeException + */ public ScriptMeta getScriptMeta(Address address) throws IOException, NodeException { JsonNode json = asJson(get("/addresses/scriptInfo/" + address.toString() + "/meta")); if (json.hasNonNull("meta")) @@ -228,10 +365,26 @@ public ScriptMeta getScriptMeta(Address address) throws IOException, NodeExcepti // ALIAS //=============== + /** + * Get a list of aliases associated with a given address + * + * @param address address base58 encoded + * @return sequence of Alias object + * @throws IOException + * @throws NodeException + */ public List getAliasesByAddress(Address address) throws IOException, NodeException { return asType(get("/alias/by-address/" + address.toString()), TypeRef.ALIASES); } + /** + * Get an address associated with a given alias. Alias should be plain text without an 'alias' prefix and chain ID. + * + * @param alias alias + * @return Address object + * @throws IOException + * @throws NodeException + */ public Address getAddressByAlias(Alias alias) throws IOException, NodeException { return Address.as(asJson(get("/alias/by-alias/" + alias.name())).get("address").asText()); } @@ -240,14 +393,47 @@ public Address getAddressByAlias(Alias alias) throws IOException, NodeException // ASSETS //=============== + /** + * Get asset balance distribution by addresses at a given height. + * Max number of addresses is set by waves.rest-api.distribution-address-limit, 1000 by default. + * + * @param assetId asset ID base58 encoded + * @param height blockchain height + * @return AssetDistribution object + * @throws IOException + * @throws NodeException + */ public AssetDistribution getAssetDistribution(AssetId assetId, int height) throws IOException, NodeException { return getAssetDistribution(assetId, height, 1000); } + /** + * Get asset balance distribution by addresses at a given height. + * Max number of addresses is set by waves.rest-api.distribution-address-limit, 1000 by default. + * + * @param assetId asset ID base58 encoded + * @param height blockchain height + * @param limit number of addresses to be returned + * @return AssetDistribution object + * @throws IOException + * @throws NodeException + */ public AssetDistribution getAssetDistribution(AssetId assetId, int height, int limit) throws IOException, NodeException { return getAssetDistribution(assetId, height, limit, null); } + /** + * Get asset balance distribution by addresses at a given height. + * Max number of addresses is set by waves.rest-api.distribution-address-limit, 1000 by default. + * + * @param assetId asset ID base58 encoded + * @param height blockchain height + * @param limit number of addresses to be returned + * @param after address + * @return AssetDistribution object + * @throws IOException + * @throws NodeException + */ public AssetDistribution getAssetDistribution(AssetId assetId, int height, int limit, Address after) throws IOException, NodeException { RequestBuilder request = get("/assets/" + assetId.toString() + "/distribution/" + height + "/limit/" + limit); if (after != null) @@ -255,6 +441,14 @@ public AssetDistribution getAssetDistribution(AssetId assetId, int height, int l return asType(request, TypeRef.ASSET_DISTRIBUTION); } + /** + * Get account balances in all or specified assets (excluding WAVES) at a given address. + * + * @param address address base58 encoded + * @return sequence of AssetBalance object + * @throws IOException + * @throws NodeException + */ public List getAssetsBalance(Address address) throws IOException, NodeException { return mapper.readerFor(TypeRef.ASSET_BALANCES) .readValue(asJson(get("/assets/balance/" + address.toString())).get("balances")); @@ -275,17 +469,43 @@ public List getAssetsBalance(Address address, List assetI ).get("balances")); } + /** + * Get the account balance in a given asset. 0 for non-existent asset + * + * @param address address base58 encoded + * @param assetId asset ID base58 encoded + * @return value of account balance in a given asset, 0 for non-existent asset + * @throws IOException + * @throws NodeException + */ public long getAssetBalance(Address address, AssetId assetId) throws IOException, NodeException { return asJson(get("/assets/balance/" + address.toString() + "/" + assetId.toString())) .get("balance").asLong(); } + /** + * Get detailed information about a given asset + * + * @param assetId asset ID base58 encoded + * @see fields descriptions + * @return AssetDetails object + * @throws IOException + * @throws NodeException + */ public AssetDetails getAssetDetails(AssetId assetId) throws IOException, NodeException { return asType(get("/assets/details/" + assetId.toString()).addParameter("full", "true"), TypeRef.ASSET_DETAILS); } //todo what if some asset doesn't exist? (error json with code and message) Either in java? + /** + * Get detailed information about a given asset + * + * @param assetIds sequence of assets ID's base58 encoded + * @return sequence of AssetDetails + * @throws IOException + * @throws NodeException + */ public List getAssetsDetails(List assetIds) throws IOException, NodeException { RequestBuilder request = get("/assets/details").addParameter("full", "true"); assetIds.forEach(id -> request.addParameter("id", id.toString())); @@ -293,14 +513,41 @@ public List getAssetsDetails(List assetIds) throws IOExce return asType(request, TypeRef.ASSETS_DETAILS); } + /** + * Get a list of non-fungible tokens at a given address + * + * @param address address base58 encoded + * @return sequence of AssetDetails + * @throws IOException + * @throws NodeException + */ public List getNft(Address address) throws IOException, NodeException { return this.getNft(address, 1000); } + /** + * Get a list of non-fungible tokens at a given address + * + * @param address address base58 encoded + * @param limit number of addresses to be returned + * @return sequence of AssetDetails + * @throws IOException + * @throws NodeException + */ public List getNft(Address address, int limit) throws IOException, NodeException { return this.getNft(address, limit, null); } + /** + * Get a list of non-fungible tokens at a given address + * + * @param address address base58 encoded + * @param limit number of addresses to be returned + * @param after ID of the token to paginate after + * @return sequence of AssetDetails + * @throws IOException + * @throws NodeException + */ public List getNft(Address address, int limit, AssetId after) throws IOException, NodeException { RequestBuilder request = get("/assets/nft/" + address.toString() + "/limit/" + limit); if (after != null) @@ -317,6 +564,8 @@ public List getNft(Address address, int limit, AssetId after) thro * Returns current blockchain rewards info * * @return @return Rewards + * @throws IOException + * @throws NodeException */ public BlockchainRewards getBlockchainRewards() throws IOException, NodeException { return asType(get("/blockchain/rewards"), TypeRef.BLOCKCHAIN_REWARDS); @@ -326,6 +575,8 @@ public BlockchainRewards getBlockchainRewards() throws IOException, NodeExceptio * Returns miner’s reward status at height * * @return Rewards + * @throws IOException + * @throws NodeException */ public BlockchainRewards getBlockchainRewards(int height) throws IOException, NodeException { return asType(get("/blockchain/rewards/" + height), TypeRef.BLOCKCHAIN_REWARDS); @@ -335,20 +586,52 @@ public BlockchainRewards getBlockchainRewards(int height) throws IOException, No // BLOCKS //=============== + /** + * Get the current blockchain height + * + * @return current blockchain height + * @throws IOException + * @throws NodeException + */ public int getHeight() throws IOException, NodeException { return asJson(get("/blocks/height")).get("height").asInt(); } + /** + * Get a block by its ID + * + * @param blockId block ID base58 encoded + * @return height of block with {blockId} + * @throws IOException + * @throws NodeException + */ public int getBlockHeight(Base58String blockId) throws IOException, NodeException { return asJson(get("/blocks/height/" + blockId.toString())) .get("height").asInt(); } + /** + * Get height of the most recent block such that its timestamp does not exceed the given {timestamp}. + * + * @param timestamp timestamp + * @return height of block + * @throws IOException + * @throws NodeException + */ public int getBlockHeight(long timestamp) throws IOException, NodeException { return asJson(get("/blocks/heightByTimestamp/" + timestamp)) .get("height").asInt(); } + /** + * Average delay in milliseconds between last blockNum blocks starting from block with id + * + * @param startBlockId block ID base58 encoded + * @param blocksNum number of blocks to count delay + * @return average delay in milliseconds + * @throws IOException + * @throws NodeException + */ public long getBlocksDelay(Base58String startBlockId, int blocksNum) throws IOException, NodeException { return asJson(get("/blocks/delay/" + startBlockId.toString() + "/" + blocksNum)) .get("delay").asLong(); @@ -365,6 +648,14 @@ public BlockHeaders getBlockHeaders(int height) throws IOException, NodeExceptio return asType(get("/blocks/headers/at/" + height), TypeRef.BLOCK_HEADERS); } + /** + * Returns headers of a given block + * + * @param blockId block ID base58 encoded + * @return block object without transactions + * @throws IOException + * @throws NodeException + */ public BlockHeaders getBlockHeaders(Base58String blockId) throws IOException, NodeException { return asType(get("/blocks/headers/" + blockId.toString()), TypeRef.BLOCK_HEADERS); } @@ -375,7 +666,8 @@ public BlockHeaders getBlockHeaders(Base58String blockId) throws IOException, No * @param fromHeight start block * @param toHeight end block * @return sequences of block objects without transactions - * @throws IOException if no block exists at the given height + * @throws IOException + * @throws NodeException */ public List getBlocksHeaders(int fromHeight, int toHeight) throws IOException, NodeException { return asType(get("/blocks/headers/seq/" + fromHeight + "/" + toHeight), TypeRef.BLOCKS_HEADERS); @@ -385,7 +677,8 @@ public List getBlocksHeaders(int fromHeight, int toHeight) throws * Returns last block header * * @return block object without transactions - * @throws IOException if no block exists at the given height + * @throws IOException + * @throws NodeException */ public BlockHeaders getLastBlockHeaders() throws IOException, NodeException { return asType(get("/blocks/headers/last"), TypeRef.BLOCK_HEADERS); @@ -396,7 +689,8 @@ public BlockHeaders getLastBlockHeaders() throws IOException, NodeException { * * @param height blockchain height * @return block object - * @throws IOException if no block exists at the given height + * @throws IOException + * @throws NodeException */ public Block getBlock(int height) throws IOException, NodeException { return asType(get("/blocks/at/" + height), TypeRef.BLOCK); @@ -407,24 +701,60 @@ public Block getBlock(int height) throws IOException, NodeException { * * @param blockId block id * @return block object - * @throws IOException if no block with the given signature exists + * @throws IOException + * @throws NodeException */ public Block getBlock(Base58String blockId) throws IOException, NodeException { return asType(get("/blocks/" + blockId.toString()), TypeRef.BLOCK); } + /** + * Get blocks at a given range of heights. + * Max range {from}-{to} is limited by rest-api.blocks-request-limit, 100 by default. + * + * @param fromHeight start block height + * @param toHeight end block height + * @return sequence of block objects + * @throws IOException + * @throws NodeException + */ public List getBlocks(int fromHeight, int toHeight) throws IOException, NodeException { return asType(get("/blocks/seq/" + fromHeight + "/" + toHeight), TypeRef.BLOCKS); } + /** + * Returns first block + * + * @return block object + * @throws IOException + * @throws NodeException + */ public Block getGenesisBlock() throws IOException, NodeException { return asType(get("/blocks/first"), TypeRef.BLOCK); } + /** + * Get the block at the current blockchain height + * + * @return block object + * @throws IOException + * @throws NodeException + */ public Block getLastBlock() throws IOException, NodeException { return asType(get("/blocks/last"), TypeRef.BLOCK); } + /** + * Get a list of blocks forged by a given address. + * Max range {from}-{to} is limited by rest-api.blocks-request-limit, 100 by default. + * + * @param generator address base58 encoded + * @param fromHeight start block height + * @param toHeight end block height + * @return sequence of block objects + * @throws IOException + * @throws NodeException + */ public List getBlocksGeneratedBy(Address generator, int fromHeight, int toHeight) throws IOException, NodeException { return asType(get( "/blocks/address/" + generator.toString() + "/" + fromHeight + "/" + toHeight), TypeRef.BLOCKS); @@ -434,6 +764,13 @@ public List getBlocksGeneratedBy(Address generator, int fromHeight, int t // NODE //=============== + /** + * Get Waves node version + * + * @return waves node version + * @throws IOException + * @throws NodeException + */ public String getVersion() throws IOException, NodeException { return asJson(get("/node/version")).get("version").asText(); } @@ -469,10 +806,28 @@ public List getSuspendedPeers() throws NodeException, IOException // DEBUG //=============== + /** + * Get history of the regular balance at a given address. + * Max depth is set by waves.db.max-rollback-depth, 2000 by default + * + * @param address address base58 encoded + * @return sequence of HistoryBalance objects + * @throws IOException + * @throws NodeException + */ public List getBalanceHistory(Address address) throws IOException, NodeException { return asType(get("/debug/balances/history/" + address.toString()), TypeRef.HISTORY_BALANCES); } + /** + * Validates a transaction and measures time spent in milliseconds. + * You should use the JSON transaction format with proofs + * + * @param transaction signed transaction + * @return validation result + * @throws IOException + * @throws NodeException + */ public Validation validateTransaction(T transaction) throws IOException, NodeException { return asType(post("/debug/validate") .setEntity(new StringEntity(transaction.toJson(), ContentType.APPLICATION_JSON)), TypeRef.VALIDATION); @@ -482,14 +837,38 @@ public Validation validateTransaction(T transaction) thr // LEASING //=============== + /** + * Get all active leases involving a given address + * + * @param address address base58 encoded + * @return sequence of LeaseInfo objects + * @throws IOException + * @throws NodeException + */ public List getActiveLeases(Address address) throws IOException, NodeException { return asType(get("/leasing/active/" + address.toString()), TypeRef.LEASES_INFO); } + /** + * Get lease parameters by lease ID + * + * @param leaseId lease ID base58 encoded + * @return LeaseInfo object + * @throws IOException + * @throws NodeException + */ public LeaseInfo getLeaseInfo(Id leaseId) throws IOException, NodeException { return asType(get("/leasing/info/" + leaseId.toString()), TypeRef.LEASE_INFO); } + /** + * Get lease parameters by lease IDs + * + * @param leaseIds sequence of lease IDs base58 encoded + * @return sequence of LeaseInfo objects + * @throws IOException + * @throws NodeException + */ public List getLeasesInfo(List leaseIds) throws IOException, NodeException { ObjectNode jsonBody = JSON_MAPPER.createObjectNode(); ArrayNode jsonIds = jsonBody.putArray("ids"); @@ -501,6 +880,14 @@ public List getLeasesInfo(List leaseIds) throws IOException, Node .setEntity(body), TypeRef.LEASES_INFO); } + /** + * Get lease parameters by lease IDs + * + * @param leaseIds sequence of lease IDs base58 encoded + * @return sequence of LeaseInfo objects + * @throws IOException + * @throws NodeException + */ public List getLeasesInfo(Id... leaseIds) throws IOException, NodeException { return getLeasesInfo(asList(leaseIds)); } @@ -509,13 +896,32 @@ public List getLeasesInfo(Id... leaseIds) throws IOException, NodeExc // TRANSACTIONS //=============== + /** + * Get the minimum fee for a given transaction + * + * @param transaction Transaction data in JSON + * including type and senderPublicKey. + * To calculate a sponsored fee, specify feeAssetId. fee and sender are ignored. + * @return amount fee with asset id + * @throws IOException + * @throws NodeException + */ public Amount calculateTransactionFee(T transaction) throws IOException, NodeException { JsonNode json = asJson(post("/transactions/calculateFee").setEntity(new StringEntity(transaction.toJson(), ContentType.APPLICATION_JSON))); return Amount.of(json.get("feeAmount").asLong(), JsonSerializer.assetIdFromJson(json.get("feeAssetId"))); } - /* - example to javadoc: IssueTransaction tx = broadcast(IssueTransaction.with("", 1, 0).get()); + /** + * Broadcast a signed transaction. + * Check out how to use this endpoint + * + * @param transaction Transaction data in JSON + * including type and signature/proofs. + *
IssueTransaction tx = broadcast(IssueTransaction.with("", 1, 0).get());
+ * + * @return Transaction object + * @throws IOException + * @throws NodeException */ public T broadcast(T transaction) throws IOException, NodeException { //noinspection unchecked @@ -524,6 +930,14 @@ public T broadcast(T transaction) throws IOException, No TypeRef.TRANSACTION); } + /** + * Broadcast a signed ethereum transaction. + * + * @param ethTransaction transaction data + * @return EthRpcResponse object + * @throws IOException + * @throws NodeException + */ public EthRpcResponse broadcastEthTransaction(EthereumTransaction ethTransaction) throws IOException, NodeException { HttpUriRequest rq = buildSendRawTransactionRq(ethTransaction.toRawHexString()); ObjectNode rs = sendEthRequest(rq); @@ -535,7 +949,8 @@ public EthRpcResponse broadcastEthTransaction(EthereumTransaction ethTransaction * * @param txId object ID * @return object object - * @throws IOException if no object with the given ID exists + * @throws IOException + * @throws NodeException */ public TransactionInfo getTransactionInfo(Id txId) throws IOException, NodeException { return asType(get("/transactions/info/" + txId.toString()), TypeRef.TRANSACTION_INFO); @@ -546,7 +961,8 @@ public TransactionInfo getTransactionInfo(Id txId) throws IOException, NodeExcep * * @param txId object ID * @return object object - * @throws IOException if no object with the given ID exists + * @throws IOException + * @throws NodeException */ public T getTransactionInfo(Id txId, Class transactionInfoClass) throws IOException, NodeException { return transactionInfoClass.cast( @@ -554,6 +970,7 @@ public T getTransactionInfo(Id txId, Class transa } /** + * * @param txIds IDs of transactions * @return info about requested transactions * @throws IOException @@ -587,7 +1004,8 @@ public List getTransactionsInfo(List txIds, C * * @param address address * @return list of transactions - * @throws IOException if something going wrong + * @throws IOException + * @throws NodeException */ public List getTransactionsByAddress(Address address) throws IOException, NodeException { return getTransactionsByAddress(address, 1000); @@ -599,7 +1017,8 @@ public List getTransactionsByAddress(Address address) throws IO * @param address address * @param limit transactions limit * @return list of transactions - * @throws IOException if something going wrong + * @throws IOException + * @throws NodeException */ public List getTransactionsByAddress(Address address, int limit) throws IOException, NodeException { return getTransactionsByAddress(address, limit, null); @@ -612,7 +1031,8 @@ public List getTransactionsByAddress(Address address, int limit * @param limit transactions limit * @param afterTxId separate transaction id * @return list of transactions - * @throws IOException if something going wrong + * @throws IOException + * @throws NodeException */ public List getTransactionsByAddress(Address address, int limit, Id afterTxId) throws IOException, NodeException { RequestBuilder request = get("/transactions/address/" + address.toString() + "/limit/" + limit); @@ -626,11 +1046,30 @@ public List getTransactionsByAddress(Address address, int limit .readValue(asJson(request).get(0)); } + /** + * Get transaction statuses by their ID. + * Transactions in the response are in the same order as in the request. + * + * @param txId transaction ID + * @return TransactionStatus object + * @throws IOException + * @throws NodeException + */ public TransactionStatus getTransactionStatus(Id txId) throws IOException, NodeException { return asType(get("/transactions/status").addParameter("id", txId.toString()), TypeRef.TRANSACTIONS_STATUS).get(0); } + /** + * Get transaction statuses by their ID. + * Max number of transactions is set by waves.rest-api.transactions-by-address-limit, 1000 by default. + * Transactions in the response are in the same order as in the request. + * + * @param txIds sequence of transaction IDs + * @return sequence of TransactionStatus objects + * @throws IOException + * @throws NodeException + */ public List getTransactionsStatus(List txIds) throws IOException, NodeException { ObjectNode jsonBody = JSON_MAPPER.createObjectNode(); ArrayNode jsonIds = jsonBody.putArray("ids"); @@ -642,18 +1081,50 @@ public List getTransactionsStatus(List txIds) throws IOEx .setEntity(body), TypeRef.TRANSACTIONS_STATUS); } + /** + * Get transaction statuses by their ID. + * Max number of transactions is set by waves.rest-api.transactions-by-address-limit, 1000 by default. + * Transactions in the response are in the same order as in the request. + * + * @param txIds sequence of transaction IDs + * @return sequence of TransactionStatus objects + * @throws IOException + * @throws NodeException + */ public List getTransactionsStatus(Id... txIds) throws IOException, NodeException { return getTransactionsStatus(asList(txIds)); } + /** + * Get an unconfirmed transaction by its ID + * + * @param txId transaction ID + * @return Transaction object + * @throws IOException + * @throws NodeException + */ public Transaction getUnconfirmedTransaction(Id txId) throws IOException, NodeException { return asType(get("/transactions/unconfirmed/info/" + txId.toString()), TypeRef.TRANSACTION); } + /** + * Get a list of transactions in node's UTX pool + * + * @return sequence of Transaction objects + * @throws IOException + * @throws NodeException + */ public List getUnconfirmedTransactions() throws IOException, NodeException { return asType(get("/transactions/unconfirmed"), TypeRef.TRANSACTIONS); } + /** + * Get the number of transactions in the UTX pool + * + * @return number of transactions in the UTX pool + * @throws IOException + * @throws NodeException + */ public int getUtxSize() throws IOException, NodeException { return asJson(get("/transactions/unconfirmed/size")).get("size").asInt(); } @@ -662,10 +1133,27 @@ public int getUtxSize() throws IOException, NodeException { // UTILS //=============== + /** + * Compiles string code to base64 script representation + * + * @param source script source + * @return ScripInfo object + * @throws IOException + * @throws NodeException + */ public ScriptInfo compileScript(String source) throws IOException, NodeException { return compileScript(source, false); } + /** + * Compiles string code to base64 script representation + * + * @param source script source + * @param enableCompaction if true, compacts the contract. False by default + * @return ScripInfo object + * @throws IOException + * @throws NodeException + */ public ScriptInfo compileScript(String source, boolean enableCompaction) throws IOException, NodeException { return asType(post("/utils/script/compileCode") .addHeader("Content-Type", "text/plain") @@ -674,6 +1162,14 @@ public ScriptInfo compileScript(String source, boolean enableCompaction) throws TypeRef.SCRIPT_INFO); } + /** + * Decompiles base64 script representation to string code + * + * @param compiledScript base64 script + * @return string code + * @throws IOException + * @throws NodeException + */ public String decompileScript(Base64String compiledScript) throws IOException, NodeException { return asJson(post("/utils/script/decompile") .addHeader("Content-Type", "application/json") @@ -682,6 +1178,14 @@ public String decompileScript(Base64String compiledScript) throws IOException, N .asText(); } + /** + * Get asset details by ethereum assetId + * + * @param asset ethereum assetId + * @return asset details + * @throws IOException + * @throws NodeException + */ public String ethToWavesAsset(String asset) throws NodeException, IOException { return asType( get("/eth/assets").addParameter("id", asset), @@ -693,6 +1197,14 @@ public String ethToWavesAsset(String asset) throws NodeException, IOException { // WAITINGS //=============== + /** + * Waiting for include transaction in the blockchain + * + * @param id transaction ID + * @param waitingInSeconds waiting time + * @return TransactionInfo object + * @throws IOException + */ public TransactionInfo waitForTransaction(Id id, int waitingInSeconds) throws IOException { int pollingIntervalInMillis = 100; @@ -715,22 +1227,60 @@ public TransactionInfo waitForTransaction(Id id, int waitingInSeconds) throws IO throw new IOException("Could not wait for transaction " + id + " in " + waitingInSeconds + " seconds", lastException); } + /** + * Waiting for include transaction in the blockchain + * + * @param id transaction ID + * @return TransactionInfo object + * @throws IOException + */ public TransactionInfo waitForTransaction(Id id) throws IOException { return waitForTransaction(id, blockInterval); } + /** + * Waiting for include transaction in the blockchain + * + * @param id transaction ID + * @param infoClass type of TransactionInfo object + * @return TransactionInfo object + * @throws IOException + */ public T waitForTransaction(Id id, Class infoClass) throws IOException { return infoClass.cast(waitForTransaction(id)); } + /** + * Waiting for include transaction in the blockchain + * + * @param tx TransactionInfo object + * @return TransactionInfo object + * @throws IOException + */ public TransactionInfo waitForTransaction(T tx) throws IOException { return waitForTransaction(tx.id()); } + /** + * Waiting for include transaction in the blockchain + * + * @param tx TransactionInfo object + * @param infoClass type of TransactionInfo object + * @return TransactionInfo object + * @throws IOException + */ public TI waitForTransaction(T tx, Class infoClass) throws IOException { return waitForTransaction(tx.id(), infoClass); } + /** + * Waiting for include transaction in the blockchain + * + * @param ids sequence of transactions ID's + * @param waitingInSeconds waiting time + * @throws IOException + * @throws NodeException + */ public void waitForTransactions(List ids, int waitingInSeconds) throws IOException, NodeException { int pollingIntervalInMillis = 1000; @@ -759,14 +1309,37 @@ public void waitForTransactions(List ids, int waitingInSeconds) throws IOExc " transactions in " + waitingInSeconds + " seconds: " + unconfirmed, lastException); } + /** + * Waiting for include transaction in the blockchain + * + * @param ids sequence of transactions ID's + * @throws IOException + * @throws NodeException + */ public void waitForTransactions(List ids) throws IOException, NodeException { waitForTransactions(ids, blockInterval); } + /** + * Waiting for include transaction in the blockchain + * + * @param ids sequence of transactions ID's + * @throws IOException + * @throws NodeException + */ public void waitForTransactions(Id... ids) throws IOException, NodeException { waitForTransactions(asList(ids)); } + /** + * Waiting for target blockchain height + * + * @param target target blockchain height + * @param waitingInSeconds waiting time + * @return blockchain height after waiting + * @throws IOException + * @throws NodeException + */ public int waitForHeight(int target, int waitingInSeconds) throws IOException, NodeException { int start = this.getHeight(); int prev = start; @@ -794,16 +1367,41 @@ else if (current > prev) { ": height " + prev + " did not grow for " + waitingInSeconds + " seconds"); } + /** + * Waiting for target blockchain height + * + * @param expectedHeight expected height of blockchain + * @return blockchain height after waiting + * @throws IOException + * @throws NodeException + */ public int waitForHeight(int expectedHeight) throws IOException, NodeException { return waitForHeight(expectedHeight, blockInterval * 3); } + /** + * Waiting for target blockchain height + * + * @param blocksCount number of skipped blocks + * @param waitingInSeconds waiting time + * @return blockchain height after waiting + * @throws IOException + * @throws NodeException + */ public int waitBlocks(int blocksCount, int waitingInSeconds) throws IOException, NodeException { if (waitingInSeconds < 1) throw new IllegalStateException("waitBlocks: waiting value must be positive. Current: " + waitingInSeconds); return waitForHeight(getHeight() + blocksCount, waitingInSeconds); } + /** + * Waiting for target blockchain height + * + * @param blocksCount number of skipped blocks + * @return blockchain height after waiting + * @throws IOException + * @throws NodeException + */ public int waitBlocks(int blocksCount) throws IOException, NodeException { return waitBlocks(blocksCount, blockInterval * 3); }