From 075d8d06a2020897a93d790822dd9b7fe81c270b Mon Sep 17 00:00:00 2001 From: Jason Paulos Date: Wed, 12 Oct 2022 10:56:16 -0700 Subject: [PATCH] Box storage merge develop (#668) --- .test-env | 2 + CHANGELOG.md | 12 ++++++ Makefile | 5 ++- README.md | 4 +- package.json | 2 +- src/client/algod.js | 21 ++++++++++ src/client/v2/algod/algod.ts | 18 ++++++++ src/client/v2/algod/getBlockHash.ts | 18 ++++++++ src/client/v2/indexer/lookupBlock.ts | 9 ++++ src/client/v2/indexer/searchAccounts.ts | 2 +- test-harness.sh | 56 ++++++++++++++++++++++++- tests/cucumber/steps/steps.js | 14 +++++++ tests/cucumber/unit.tags | 3 ++ 13 files changed, 160 insertions(+), 6 deletions(-) create mode 100644 src/client/v2/algod/getBlockHash.ts diff --git a/.test-env b/.test-env index eff6690c0..9135343b7 100644 --- a/.test-env +++ b/.test-env @@ -3,6 +3,8 @@ SDK_TESTING_URL="https://github.com/algorand/algorand-sdk-testing" SDK_TESTING_BRANCH="feature/box-storage" SDK_TESTING_HARNESS="test-harness" +INSTALL_ONLY=0 + VERBOSE_HARNESS=0 # WARNING: If set to 1, new features will be LOST when downloading the test harness. diff --git a/CHANGELOG.md b/CHANGELOG.md index a506677f8..e4114e3e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +# v1.21.0 + +## What's Changed + +### Enhancements + +- Enhancement: Removing more unused steps by @tzaffi in https://github.com/algorand/js-algorand-sdk/pull/637 +- Enhancement: Add deprecation tag to algod v1 client by @algochoi in https://github.com/algorand/js-algorand-sdk/pull/642 +- enhancement: add unit test for ParticipationUpdates field by @shiqizng in https://github.com/algorand/js-algorand-sdk/pull/652 + +**Full Changelog**: https://github.com/algorand/js-algorand-sdk/compare/v1.20.0...v1.21.0 + # v1.20.0 ## What's Changed diff --git a/Makefile b/Makefile index 6f9bb461a..3fdc3afab 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,10 @@ display-all-js-steps: tail -n +135 tests/cucumber/steps/steps.js | grep -v '^ *//' | awk "/(Given|Then|When)/,/',/" | grep -E "\'.+\'" | sed "s/^[^']*'\([^']*\)'.*/\1/g" harness: - ./test-harness.sh + ./test-harness.sh up + +harness-down: + ./test-harness.sh down docker-build: docker build -t js-sdk-testing -f tests/cucumber/docker/Dockerfile $(CURDIR) --build-arg TEST_BROWSER --build-arg CI=true diff --git a/README.md b/README.md index 31e26cc80..69e6e9cec 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Include a minified browser bundle directly in your HTML like so: ```html @@ -32,7 +32,7 @@ or ```html diff --git a/package.json b/package.json index 2803b38a3..0f4a53a46 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "algosdk", - "version": "1.20.0", + "version": "1.21.0", "description": "The official JavaScript SDK for Algorand", "main": "dist/cjs/index.js", "module": "dist/esm/index.js", diff --git a/src/client/algod.js b/src/client/algod.js index c1609454e..284870f4f 100644 --- a/src/client/algod.js +++ b/src/client/algod.js @@ -1,6 +1,7 @@ const { default: HTTPClient } = require('./client'); const { setSendTransactionHeaders } = require('./v2/algod/sendRawTransaction'); +/** @deprecated v1 algod APIs are deprecated, please use the v2 client */ function Algod( token = '', baseServer = 'http://r2.algorand.network', @@ -20,6 +21,7 @@ function Algod( * Takes an object and convert its note field to Buffer, if exist. * @param o * @returns {*} + * @deprecated v1 algod APIs are deprecated, please use the v2 client */ function noteb64ToNote(o) { if (!(o.noteb64 === undefined || o.noteb64 === null)) { @@ -33,6 +35,7 @@ function Algod( * status retrieves the StatusResponse from the running node * @param headerObj, optional * @returns {Promise<*>} + * @deprecated v1 algod APIs are deprecated, please use the v2 client */ this.status = async (headerObj = {}) => { const res = await c.get('/v1/status', {}, headerObj); @@ -43,6 +46,7 @@ function Algod( * healthCheck returns an empty object iff the node is running * @param headerObj, optional * @returns {Promise<*>} + * @deprecated v1 algod APIs are deprecated, please use the v2 client */ this.healthCheck = async (headerObj = {}) => { const res = await c.get('/health', {}, headerObj); @@ -58,6 +62,7 @@ function Algod( * @param roundNumber * @param headerObj, optional * @returns {Promise<*>} + * @deprecated v1 algod APIs are deprecated, please use the v2 client */ this.statusAfterBlock = async (roundNumber, headerObj = {}) => { if (!Number.isInteger(roundNumber)) @@ -76,6 +81,7 @@ function Algod( * @param maxTxns - number * @param headerObj, optional * @returns {Promise<*>} + * @deprecated v1 algod APIs are deprecated, please use the v2 client */ this.pendingTransactions = async (maxTxns, headerObj = {}) => { if (!Number.isInteger(maxTxns)) throw Error('maxTxns should be an integer'); @@ -101,6 +107,7 @@ function Algod( * versions retrieves the VersionResponse from the running node * @param headerObj, optional * @returns {Promise<*>} + * @deprecated v1 algod APIs are deprecated, please use the v2 client */ this.versions = async (headerObj = {}) => { const res = await c.get('/versions', {}, headerObj); @@ -111,6 +118,7 @@ function Algod( * LedgerSupply gets the supply details for the specified node's Ledger * @param headerObj, optional * @returns {Promise<*>} + * @deprecated v1 algod APIs are deprecated, please use the v2 client */ this.ledgerSupply = async (headerObj = {}) => { const res = await c.get('/v1/ledger/supply', {}, headerObj); @@ -125,6 +133,7 @@ function Algod( * @param maxTxns - number, optional * @param headers, optional * @returns {Promise<*>} + * @deprecated v1 algod APIs are deprecated, please use the v2 client */ this.transactionByAddress = async ( addr, @@ -161,6 +170,7 @@ function Algod( * @param maxTxns - number, optional * @param headerObj, optional * @returns {Promise<*>} + * @deprecated v1 algod APIs are deprecated, please use the v2 client */ this.transactionByAddressAndDate = async ( addr, @@ -188,6 +198,7 @@ function Algod( * @param txid * @param headerObj, optional * @returns {Promise<*>} + * @deprecated v1 algod APIs are deprecated, please use the v2 client */ this.transactionById = async (txid, headerObj = {}) => { const res = await c.get(`/v1/transaction/${txid}`, {}, headerObj); @@ -203,6 +214,7 @@ function Algod( * @param txid * @param headerObj, optional * @returns {Promise<*>} + * @deprecated v1 algod APIs are deprecated, please use the v2 client */ this.transactionInformation = async (addr, txid, headerObj = {}) => { const res = await c.get( @@ -221,6 +233,7 @@ function Algod( * @param txid * @param headerObj, optional * @returns {Promise<*>} + * @deprecated v1 algod APIs are deprecated, please use the v2 client */ this.pendingTransactionInformation = async (txid, headerObj = {}) => { const res = await c.get(`/v1/transactions/pending/${txid}`, {}, headerObj); @@ -235,6 +248,7 @@ function Algod( * @param addr - string * @param headerObj, optional * @returns {Promise<*>} + * @deprecated v1 algod APIs are deprecated, please use the v2 client */ this.accountInformation = async (addr, headerObj = {}) => { const res = await c.get(`/v1/account/${addr}`, {}, headerObj); @@ -246,6 +260,7 @@ function Algod( * @param index - number * @param headerObj, optional * @returns {Promise<*>} + * @deprecated v1 algod APIs are deprecated, please use the v2 client */ this.assetInformation = async (index, headerObj = {}) => { const res = await c.get(`/v1/asset/${index}`, {}, headerObj); @@ -256,6 +271,7 @@ function Algod( * suggestedFee gets the recommended transaction fee from the node * @param headerObj, optional * @returns {Promise<*>} + * @deprecated v1 algod APIs are deprecated, please use the v2 client */ this.suggestedFee = async (headerObj = {}) => { const res = await c.get('/v1/transactions/fee', {}, headerObj); @@ -267,6 +283,7 @@ function Algod( * @param txn - Uin8Array * @param headerObj, optional * @returns {Promise<*>} + * @deprecated v1 algod APIs are deprecated, please use the v2 client */ this.sendRawTransaction = async (txn, headerObj = {}) => { const txHeaders = setSendTransactionHeaders(headerObj); @@ -279,6 +296,7 @@ function Algod( * @param txn - Array of Uin8Array * @param headerObj, optional * @returns {Promise<*>} + * @deprecated v1 algod APIs are deprecated, please use the v2 client */ this.sendRawTransactions = async (txns, headerObj = {}) => { const txHeaders = setSendTransactionHeaders(headerObj); @@ -297,6 +315,7 @@ function Algod( * getTransactionParams returns to common needed parameters for a new transaction * @param headerObj, optional * @returns {Promise<*>} + * @deprecated v1 algod APIs are deprecated, please use the v2 client */ this.getTransactionParams = async (headerObj = {}) => { const res = await c.get('/v1/transactions/params', {}, headerObj); @@ -307,6 +326,7 @@ function Algod( * suggestParams returns to common needed parameters for a new transaction, in a format the transaction builder expects * @param headerObj, optional * @returns {Object} + * @deprecated v1 algod APIs are deprecated, please use the v2 client */ this.suggestParams = async (headerObj = {}) => { const result = await this.getTransactionParams(headerObj); @@ -325,6 +345,7 @@ function Algod( * @param roundNumber * @param headerObj, optional * @returns {Promise<*>} + * @deprecated v1 algod APIs are deprecated, please use the v2 client */ this.block = async (roundNumber, headerObj = {}) => { if (!Number.isInteger(roundNumber)) diff --git a/src/client/v2/algod/algod.ts b/src/client/v2/algod/algod.ts index bd647c9f7..3175a8e79 100644 --- a/src/client/v2/algod/algod.ts +++ b/src/client/v2/algod/algod.ts @@ -9,6 +9,7 @@ import Dryrun from './dryrun'; import Genesis from './genesis'; import GetAssetByID from './getAssetByID'; import GetApplicationByID from './getApplicationByID'; +import GetBlockHash from './getBlockHash'; import GetApplicationBoxByName from './getApplicationBoxByName'; import GetApplicationBoxes from './getApplicationBoxes'; import HealthCheck from './healthCheck'; @@ -207,6 +208,23 @@ export default class AlgodClient extends ServiceClient { return new Block(this.c, roundNumber); } + /** + * Get the block hash for the block on the given round. + * + * #### Example + * ```typescript + * const roundNumber = 18038133; + * const block = await algodClient.getBlockHash(roundNumber).do(); + * ``` + * + * [Response data schema details](https://developer.algorand.org/docs/rest-apis/algod/v2/#get-v2blocksroundhash) + * @param roundNumber - The round number of the block to get. + * @category GET + */ + getBlockHash(roundNumber: number) { + return new GetBlockHash(this.c, this.intDecoding, roundNumber); + } + /** * Returns the transaction information for a specific pending transaction. * diff --git a/src/client/v2/algod/getBlockHash.ts b/src/client/v2/algod/getBlockHash.ts new file mode 100644 index 000000000..40d01b499 --- /dev/null +++ b/src/client/v2/algod/getBlockHash.ts @@ -0,0 +1,18 @@ +import JSONRequest from '../jsonrequest'; +import HTTPClient from '../../client'; +import IntDecoding from '../../../types/intDecoding'; + +export default class GetBlockHash extends JSONRequest { + round: number; + + constructor(c: HTTPClient, intDecoding: IntDecoding, roundNumber: number) { + super(c, intDecoding); + if (!Number.isInteger(roundNumber)) + throw Error('roundNumber should be an integer'); + this.round = roundNumber; + } + + path() { + return `/v2/blocks/${this.round}/hash`; + } +} diff --git a/src/client/v2/indexer/lookupBlock.ts b/src/client/v2/indexer/lookupBlock.ts index d722827cf..3b5030712 100644 --- a/src/client/v2/indexer/lookupBlock.ts +++ b/src/client/v2/indexer/lookupBlock.ts @@ -27,4 +27,13 @@ export default class LookupBlock extends JSONRequest { path() { return `/v2/blocks/${this.round}`; } + + /** + * Header only flag. When this is set to true, returned block does not contain the + * transactions. + */ + headerOnly(headerOnly: boolean) { + this.query['header-only'] = headerOnly; + return this; + } } diff --git a/src/client/v2/indexer/searchAccounts.ts b/src/client/v2/indexer/searchAccounts.ts index 31a62f02d..21b1df4b0 100644 --- a/src/client/v2/indexer/searchAccounts.ts +++ b/src/client/v2/indexer/searchAccounts.ts @@ -43,7 +43,7 @@ export default class SearchAccounts extends JSONRequest { * .do(); * ``` * @remarks - * If you are looking for accounts with the currency amount greater than 0, simply construct the query without `currencyGreaterThan` because it doesn't accept `-1`, and passing the `0` `currency-greater-than` value would exclude transactions with a 0 amount. + * If you are looking for accounts with the currency amount greater than 0, simply construct the query without `currencyGreaterThan` because it doesn't accept `-1`, and passing the `0` `currency-greater-than` value would exclude accounts with a 0 amount. * * @param greater * @category query diff --git a/test-harness.sh b/test-harness.sh index ad68eaf63..182039e1a 100755 --- a/test-harness.sh +++ b/test-harness.sh @@ -1,7 +1,47 @@ #!/usr/bin/env bash - set -euo pipefail +# test-harness.sh setup/start cucumber test environment. +# +# Configuration is managed with environment variables, the ones you +# are most likely to reconfigured are stored in '.test-env'. +# +# Variables: +# SDK_TESTING_URL - URL to algorand-sdk-testing, useful for forks. +# SDK_TESTING_BRANCH - branch to checkout, useful for new tests. +# SDK_TESTING_HARNESS - local directory that the algorand-sdk-testing repo is cloned into. +# VERBOSE_HARNESS - more output while the script runs. +# INSTALL_ONLY - installs feature files only, useful for unit tests. +# +# WARNING: If set to 1, new features will be LOST when downloading the test harness. +# REGARDLESS: modified features are ALWAYS overwritten. +# REMOVE_LOCAL_FEATURES - delete all local cucumber feature files before downloading these from github. +# +# WARNING: Be careful when turning on the next variable. +# In that case you'll need to provide all variables expected by `algorand-sdk-testing`'s `.env` +# OVERWRITE_TESTING_ENVIRONMENT=0 + +SHUTDOWN=0 +if [ $# -ne 0 ]; then + if [ $# -ne 1 ]; then + echo "this script accepts a single argument, which must be 'up' or 'down'." + exit 1 + fi + + case $1 in + 'up') + ;; # default. + 'down') + SHUTDOWN=1 + ;; + *) + echo "unknown parameter '$1'." + echo "this script accepts a single argument, which must be 'up' or 'down'." + exit 1 + ;; + esac +fi + START=$(date "+%s") THIS=$(basename "$0") @@ -23,10 +63,19 @@ if [ -d "$SDK_TESTING_HARNESS" ]; then ./scripts/down.sh popd rm -rf "$SDK_TESTING_HARNESS" + if [[ $SHUTDOWN == 1 ]]; then + echo "$THIS: network shutdown complete." + exit 0 + fi else echo "$THIS: directory $SDK_TESTING_HARNESS does not exist - NOOP" fi +if [[ $SHUTDOWN == 1 ]]; then + echo "$THIS: unable to shutdown network." + exit 1 +fi + git clone --depth 1 --single-branch --branch "$SDK_TESTING_BRANCH" "$SDK_TESTING_URL" "$SDK_TESTING_HARNESS" @@ -52,6 +101,11 @@ if [[ $VERBOSE_HARNESS == 1 ]]; then fi echo "$THIS: seconds it took to get to end of cloning and copying: $(($(date "+%s") - START))s" +if [[ $INSTALL_ONLY == 1 ]]; then + echo "$THIS: configured to install feature files only. Not starting test harness environment." + exit 0 +fi + ## Start test harness environment pushd "$SDK_TESTING_HARNESS" diff --git a/tests/cucumber/steps/steps.js b/tests/cucumber/steps/steps.js index a96f1f088..ef2bbb78c 100644 --- a/tests/cucumber/steps/steps.js +++ b/tests/cucumber/steps/steps.js @@ -2225,6 +2225,13 @@ module.exports = function getSteps(options) { } ); + When( + 'we make a Lookup Block call against round {int} and header {string}', + async function (int, string) { + await this.indexerClient.lookupBlock(int).headerOnly(string).do(); + } + ); + When( 'we make a Lookup Account by ID call against account {string} with round {int}', async function (account, round) { @@ -4649,6 +4656,13 @@ module.exports = function getSteps(options) { await this.v2Client.getStateProof(int).do(); }); + When( + 'we make a Lookup Block Hash call against round {int}', + async function (int) { + await this.v2Client.getBlockHash(int).do(); + } + ); + Given( 'a base64 encoded program bytes for heuristic sanity check {string}', async function (programByteStr) { diff --git a/tests/cucumber/unit.tags b/tests/cucumber/unit.tags index 0ff7ea3f5..31f29d33c 100644 --- a/tests/cucumber/unit.tags +++ b/tests/cucumber/unit.tags @@ -5,6 +5,7 @@ @unit.applications @unit.applications.boxes @unit.atomic_transaction_composer +@unit.blocksummary @unit.dryrun @unit.dryrun.trace.application @unit.feetest @@ -16,7 +17,9 @@ @unit.rekey @unit.responses @unit.responses.231 +@unit.responses.participationupdates @unit.responses.unlimited_assets +@unit.responses.blocksummary @unit.sourcemap @unit.stateproof.paths @unit.stateproof.responses