diff --git a/.github/workflows/create-release-pr.yml b/.github/workflows/create-release-pr.yml
new file mode 100644
index 000000000..2f906361d
--- /dev/null
+++ b/.github/workflows/create-release-pr.yml
@@ -0,0 +1,230 @@
+name: Create Release PR
+
+on:
+ workflow_dispatch:
+ inputs:
+ release_version:
+ description: 'The release_version used for the release branch name, e.g. release/x.x.x'
+ default: 'x.x.x'
+ required: true
+ type: string
+ pre_release_version:
+ description: "Pre-Release version, e.g. 'beta-1'"
+ required: false
+ type: string
+
+env:
+ RELEASE_VERSION: ${{ inputs.release_version }}
+ PRE_RELEASE_VERSION: ${{ inputs.pre_release_version }}
+ RELEASE_BRANCH: release/${{ inputs.release_version }}
+
+jobs:
+ create-release-pr:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Set Release Version and Branch to Check Out
+ id: set-release
+ run: |
+ if [[ $RELEASE_VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
+ if [[ $PRE_RELEASE_VERSION =~ ^[-a-z0-9]+$ ]]; then
+ echo "release-tag: $RELEASE_VERSION-$PRE_RELEASE_VERSION"
+ echo "release-tag=$RELEASE_VERSION-$PRE_RELEASE_VERSION" >> $GITHUB_OUTPUT
+ elif [[ -n $PRE_RELEASE_VERSION ]]; then
+ echo "Input pre_release_version is not empty, but does not match the regex pattern ^[-a-z0-9]+$"
+ exit 1
+ else
+ echo "release-tag: $RELEASE_VERSION"
+ echo "release-tag=$RELEASE_VERSION" >> $GITHUB_OUTPUT
+ fi
+ else
+ echo "Version input doesn't match the regex pattern ^[0-9]+\.[0-9]+\.[0-9]+$"
+ exit 1
+ fi
+
+ - name: Checkout
+ uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+
+ - name: Create Release Branch if it does not exist
+ run: |
+ if ! git show-ref --verify --quiet "refs/remotes/origin/$RELEASE_BRANCH"; then
+ git checkout -b $RELEASE_BRANCH
+ git push --set-upstream origin $RELEASE_BRANCH
+ elif [[ $(git rev-parse --abbrev-ref HEAD) != "$RELEASE_BRANCH" ]]; then
+ echo "Current Branch: $(git rev-parse --abbrev-ref HEAD)"
+ echo "Release branch exists, make sure you're using the workflow from the release branch or delete the existing release branch."
+ exit 1
+ else
+ echo "Release branch exists and used as workflow ref."
+ fi
+
+ - name: Get Latest Release
+ id: get-release
+ run: |
+ if [[ -n $PRE_RELEASE_VERSION ]]; then
+ echo "Get the latest release"
+ tag=$(curl -L \
+ --header "Accept: application/vnd.github.v3+json" \
+ "https://api.github.com/repos/${{ github.repository }}/releases" | jq -r '.[0].tag_name')
+ echo "latest-tag=$tag" >> $GITHUB_OUTPUT
+ else
+ echo "Get the latest stable release"
+ tag=$(curl -L \
+ --header "Accept: application/vnd.github.v3+json" \
+ "https://api.github.com/repos/${{ github.repository }}/releases/latest" | jq -r '.tag_name')
+ echo "latest-tag=$tag" >> $GITHUB_OUTPUT
+ fi
+
+ - name: Build Changelog
+ uses: mikepenz/release-changelog-builder-action@v3.7.2
+ id: build-changelog
+ env:
+ PREVIOUS_VERSION: ${{ steps.get-release.outputs.latest-tag }}
+ with:
+ fromTag: ${{ env.PREVIOUS_VERSION }}
+ toTag: ${{ env.RELEASE_BRANCH }}
+ failOnError: true
+ configurationJson: |
+ {
+ "categories": [
+ {
+ "title": "## New Features",
+ "labels": [
+ "New Feature"
+ ]
+ },
+ {
+ "title": "## Enhancements",
+ "labels": [
+ "Enhancement"
+ ]
+ },
+ {
+ "title": "## Bug Fixes",
+ "labels": [
+ "Bug-Fix"
+ ]
+ },
+ {
+ "title": "## Not Yet Enabled",
+ "labels": [
+ "Not-Yet-Enabled"
+ ]
+ }
+ ],
+ "ignore_labels": [
+ "Skip-Release-Notes"
+ ],
+ "sort": {
+ "order": "ASC",
+ "on_property": "mergedAt"
+ },
+ "template": "#{{CHANGELOG}}",
+ "pr_template": "- #{{TITLE}} by @#{{AUTHOR}} in ##{{NUMBER}}"
+ }
+
+ - name: Update Changelog
+ if: ${{ env.PRE_RELEASE_VERSION == '' }}
+ env:
+ CHANGELOG_CONTENT: ${{ steps.build-changelog.outputs.changelog }}
+ PREVIOUS_VERSION: ${{ steps.get-release.outputs.latest-tag }}
+ run: |
+ echo -e "# ${RELEASE_VERSION}\n\n${CHANGELOG_CONTENT}**Full Changelog**: https://github.com/${{ github.repository }}/compare/${PREVIOUS_VERSION}...${RELEASE_VERSION}\n" | cat - CHANGELOG.md > temp && mv temp CHANGELOG.md
+
+ - name: Update Version References in Source
+ env:
+ RELEASE_TAG: ${{ steps.set-release.outputs.release-tag }}
+ run: |
+ python3 scripts/bump_version.py ${RELEASE_TAG}
+
+ - name: Commit Changes
+ uses: EndBug/add-and-commit@v9.1.3
+ env:
+ RELEASE_TAG: ${{ steps.set-release.outputs.release-tag }}
+ with:
+ message: "bump up version to ${{ env.RELEASE_TAG }}"
+
+ - name: Create Pull Request to Master
+ env:
+ CHANGELOG_CONTENT: ${{ steps.build-changelog.outputs.changelog }}
+ PREVIOUS_VERSION: ${{ steps.get-release.outputs.latest-tag }}
+ GH_TOKEN: ${{ github.token }}
+ RELEASE_TAG: ${{ steps.set-release.outputs.release-tag }}
+ run: |
+ echo -e "# What's Changed\n\n${CHANGELOG_CONTENT}**Full Changelog**: https://github.com/${{ github.repository }}/compare/${PREVIOUS_VERSION}...${RELEASE_TAG}" > tmp_msg_body.txt
+ export msg_body=$(cat tmp_msg_body.txt)
+ rm tmp_msg_body.txt
+ # Note: There's an issue adding teams as reviewers, see https://github.com/cli/cli/issues/6395
+ PULL_REQUEST_URL=$(gh pr create --base "master" \
+ --title "FOR REVIEW ONLY: ${{ github.event.repository.name }} $RELEASE_TAG" \
+ --label "Skip-Release-Notes" \
+ --label "Team Hyper Flow" \
+ --body "$msg_body" | tail -n 1)
+ if [[ $PULL_REQUEST_URL =~ ^https://github.com/${{ github.repository }}/pull/[0-9]+$ ]]; then
+ PULL_REQUEST_NUM=$(echo $PULL_REQUEST_URL | sed 's:.*/::')
+ echo "pull-request-master=$PULL_REQUEST_URL" >> $GITHUB_ENV
+ echo "pull-request-master-num=$PULL_REQUEST_NUM" >> $GITHUB_ENV
+ echo "Pull request to Master created: $PULL_REQUEST_URL"
+ else
+ echo "There was an issue creating the pull request to master branch."
+ exit 1
+ fi
+
+ - name: Create Pull Request to Develop
+ if: ${{ env.PRE_RELEASE_VERSION == '' }}
+ env:
+ GH_TOKEN: ${{ github.token }}
+ RELEASE_TAG: ${{ steps.set-release.outputs.release-tag }}
+ run: |
+ # Note: There's an issue adding teams as reviewers, see https://github.com/cli/cli/issues/6395
+ PULL_REQUEST_URL=$(gh pr create --base "develop" \
+ --title "FOR REVIEW ONLY: Merge back ${{ github.event.repository.name }} $RELEASE_TAG to develop" \
+ --label "Skip-Release-Notes" \
+ --label "Team Hyper Flow" \
+ --body "Merge back version changes to develop." | tail -n 1)
+ if [[ $PULL_REQUEST_URL =~ ^https://github.com/${{ github.repository }}/pull/[0-9]+$ ]]; then
+ echo "Pull request to Develop created: $PULL_REQUEST_URL"
+ DEVELOP_PR_MESSAGE="\nPull Request to develop: $PULL_REQUEST_URL"
+ echo "pull-request-develop-message=$DEVELOP_PR_MESSAGE" >> $GITHUB_ENV
+ else
+ echo "There was an issue creating the pull request to develop branch."
+ exit 1
+ fi
+
+ - name: Send Slack Message
+ id: slack
+ uses: slackapi/slack-github-action@v1.24.0
+ env:
+ RELEASE_TAG: ${{ steps.set-release.outputs.release-tag }}
+ SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
+ SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
+ SDK_DEPLOYMENT_URL: ${{ secrets.SDK_DEPLOYMENT_URL }}
+ with:
+ payload: |
+ {
+ "blocks": [
+ {
+ "type": "header",
+ "text": {
+ "type": "plain_text",
+ "text": "${{ github.event.repository.name }} Release PR for ${{ env.RELEASE_TAG }}"
+ }
+ },
+ {
+ "type": "section",
+ "text": {
+ "type": "mrkdwn",
+ "text": "*Approvals needed for*:\nPull Request to master: ${{ env.pull-request-master}}${{ env.pull-request-develop-message }}"
+ }
+ },
+ {
+ "type": "section",
+ "text": {
+ "type": "mrkdwn",
+ "text": "*After approvals*\nDeploy SDK using the <${{ env.SDK_DEPLOYMENT_URL }}|Deployment Pipeline> with the following parameters:\n*SDK*: ${{ github.event.repository.name }}\n*RELEASE_PR_NUM*: ${{ env.pull-request-master-num }}\n*RELEASE_VERSION*: ${{ env.RELEASE_VERSION }}\n*PRE_RELEASE_VERSION*: ${{ env.PRE_RELEASE_VERSION }}"
+ }
+ }
+ ]
+ }
diff --git a/.test-env b/.test-env
index df783a4fd..049289d7b 100644
--- a/.test-env
+++ b/.test-env
@@ -5,7 +5,7 @@ SDK_TESTING_HARNESS="test-harness"
INSTALL_ONLY=0
-VERBOSE_HARNESS=0
+VERBOSE_HARNESS=1
# WARNING: If set to 1, new features will be LOST when downloading the test harness.
# REGARDLESS: modified features are ALWAYS overwritten.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ae86c0cf8..b0bae6a4e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,17 @@
+# 2.2.0
+
+## Enhancements
+
+- DevOps: Update CODEOWNERS to only refer to the devops group by @onetechnical in #571
+- deltas: Deltas apis by @Eric-Warehime in #575
+- algod: Regen changes for Deltas endpoints by @Eric-Warehime in #590
+
+## Bug Fixes
+
+- docs: remove old example from README by @winder in #561
+
+**Full Changelog**: https://github.com/algorand/java-algorand-sdk/compare/2.1.0...2.2.0
+
# 2.1.0
## What's Changed
diff --git a/CODEOWNERS b/CODEOWNERS
index aa26c82a4..3c88c6e71 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -1,2 +1,2 @@
-.github/ @algorand/dev
-.circleci/ @algorand/dev
+.github/ @algorand/devops
+.circleci/ @algorand/devops
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 000000000..966aa2cf9
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,128 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+We as members, contributors, and leaders pledge to make participation in our
+community a harassment-free experience for everyone, regardless of age, body
+size, visible or invisible disability, ethnicity, sex characteristics, gender
+identity and expression, level of experience, education, socio-economic status,
+nationality, personal appearance, race, religion, or sexual identity
+and orientation.
+
+We pledge to act and interact in ways that contribute to an open, welcoming,
+diverse, inclusive, and healthy community.
+
+## Our Standards
+
+Examples of behavior that contributes to a positive environment for our
+community include:
+
+* Demonstrating empathy and kindness toward other people
+* Being respectful of differing opinions, viewpoints, and experiences
+* Giving and gracefully accepting constructive feedback
+* Accepting responsibility and apologizing to those affected by our mistakes,
+ and learning from the experience
+* Focusing on what is best not just for us as individuals, but for the
+ overall community
+
+Examples of unacceptable behavior include:
+
+* The use of sexualized language or imagery, and sexual attention or
+ advances of any kind
+* Trolling, insulting or derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or email
+ address, without their explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Enforcement Responsibilities
+
+Community leaders are responsible for clarifying and enforcing our standards of
+acceptable behavior and will take appropriate and fair corrective action in
+response to any behavior that they deem inappropriate, threatening, offensive,
+or harmful.
+
+Community leaders have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, and will communicate reasons for moderation
+decisions when appropriate.
+
+## Scope
+
+This Code of Conduct applies within all community spaces, and also applies when
+an individual is officially representing the community in public spaces.
+Examples of representing our community include using an official e-mail address,
+posting via an official social media account, or acting as an appointed
+representative at an online or offline event.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported to the community leaders responsible for enforcement at
+conduct@algorand.com.
+All complaints will be reviewed and investigated promptly and fairly.
+
+All community leaders are obligated to respect the privacy and security of the
+reporter of any incident.
+
+## Enforcement Guidelines
+
+Community leaders will follow these Community Impact Guidelines in determining
+the consequences for any action they deem in violation of this Code of Conduct:
+
+### 1. Correction
+
+**Community Impact**: Use of inappropriate language or other behavior deemed
+unprofessional or unwelcome in the community.
+
+**Consequence**: A private, written warning from community leaders, providing
+clarity around the nature of the violation and an explanation of why the
+behavior was inappropriate. A public apology may be requested.
+
+### 2. Warning
+
+**Community Impact**: A violation through a single incident or series
+of actions.
+
+**Consequence**: A warning with consequences for continued behavior. No
+interaction with the people involved, including unsolicited interaction with
+those enforcing the Code of Conduct, for a specified period of time. This
+includes avoiding interactions in community spaces as well as external channels
+like social media. Violating these terms may lead to a temporary or
+permanent ban.
+
+### 3. Temporary Ban
+
+**Community Impact**: A serious violation of community standards, including
+sustained inappropriate behavior.
+
+**Consequence**: A temporary ban from any sort of interaction or public
+communication with the community for a specified period of time. No public or
+private interaction with the people involved, including unsolicited interaction
+with those enforcing the Code of Conduct, is allowed during this period.
+Violating these terms may lead to a permanent ban.
+
+### 4. Permanent Ban
+
+**Community Impact**: Demonstrating a pattern of violation of community
+standards, including sustained inappropriate behavior, harassment of an
+individual, or aggression toward or disparagement of classes of individuals.
+
+**Consequence**: A permanent ban from any sort of public interaction within
+the community.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage],
+version 2.0, available at
+https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
+
+Community Impact Guidelines were inspired by [Mozilla's code of conduct
+enforcement ladder](https://github.com/mozilla/diversity).
+
+[homepage]: https://www.contributor-covenant.org
+
+For answers to common questions about this code of conduct, see the FAQ at
+https://www.contributor-covenant.org/faq. Translations are available at
+https://www.contributor-covenant.org/translations.
diff --git a/README.md b/README.md
index b25484d73..565d46a31 100644
--- a/README.md
+++ b/README.md
@@ -19,7 +19,7 @@ Maven:
com.algorand
algosdk
- 2.1.0
+ 2.2.0
```
@@ -198,13 +198,6 @@ This project uses Maven.
~$ mvn package
```
-**To run the example project**
-Use the following command in the examples directory, be sure to update your algod network address and the API token
-parameters (see examples/README for more information):
-```
-~$ mvn exec:java -Dexec.mainClass="com.algorand.algosdk.example.Main" -Dexec.args="127.0.0.1:8080 ***X-Algo-API-Token***"
-```
-
### **To test**
We are using separate version targets for production and testing to allow using JUnit5 for tests. Some IDEs, like IDEA
do not support this very well. To workaround the issue a special `ide` profile should be enabled if your IDE does not
diff --git a/pom.xml b/pom.xml
index ec8d71f2b..adadd9098 100755
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
com.algorand
algosdk
- 2.1.0
+ 2.2.0
jar
${project.groupId}:${project.artifactId}
diff --git a/scripts/bump_version.py b/scripts/bump_version.py
new file mode 100755
index 000000000..7af8f6aa0
--- /dev/null
+++ b/scripts/bump_version.py
@@ -0,0 +1,38 @@
+# This script bumps up the version in `pom.xml` and `README.md` for new releases.
+# Usage: python bump_version.py {new_version} (--read_me --pom_xml )
+
+import argparse
+import re
+
+def bump_version(new_version, file_path):
+ with open(file_path, "r") as file:
+ content = file.read()
+
+ # Replace first instance of
+ new_content = re.sub(
+ '[0-9]+\.[0-9]+\.[-a-z0-9]+',
+ f'{new_version}',
+ content, 1
+ )
+
+ with open(file_path, "w") as file:
+ file.write(new_content)
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(
+ description="updates the version for a release",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ )
+ parser.add_argument("new_version", help="New Version as major.minor.patch")
+ parser.add_argument(
+ "--read_me", default="README.md", help="path to README.md"
+ )
+ parser.add_argument(
+ "--pom_xml", default="pom.xml", help="path to pom.xml"
+ )
+
+ args = parser.parse_args()
+
+ bump_version(args.new_version, args.read_me)
+ bump_version(args.new_version, args.pom_xml)
+
diff --git a/src/main/java/com/algorand/algosdk/v2/client/algod/GetApplicationBoxByName.java b/src/main/java/com/algorand/algosdk/v2/client/algod/GetApplicationBoxByName.java
index 2eab16704..61b6a079d 100644
--- a/src/main/java/com/algorand/algosdk/v2/client/algod/GetApplicationBoxByName.java
+++ b/src/main/java/com/algorand/algosdk/v2/client/algod/GetApplicationBoxByName.java
@@ -9,8 +9,8 @@
/**
- * Given an application ID and box name, it returns the box name and value (each
- * base64 encoded). Box names must be in the goal app call arg encoding form
+ * Given an application ID and box name, it returns the round, box name, and value
+ * (each base64 encoded). Box names must be in the goal app call arg encoding form
* 'encoding:value'. For ints, use the form 'int:1234'. For raw bytes, use the form
* 'b64:A=='. For printable strings, use the form 'str:hello'. For addresses, use
* the form 'addr:XYZ...'.
diff --git a/src/main/java/com/algorand/algosdk/v2/client/algod/GetLedgerStateDelta.java b/src/main/java/com/algorand/algosdk/v2/client/algod/GetLedgerStateDelta.java
new file mode 100644
index 000000000..8bd624ac0
--- /dev/null
+++ b/src/main/java/com/algorand/algosdk/v2/client/algod/GetLedgerStateDelta.java
@@ -0,0 +1,65 @@
+package com.algorand.algosdk.v2.client.algod;
+
+import com.algorand.algosdk.v2.client.common.Client;
+import com.algorand.algosdk.v2.client.common.HttpMethod;
+import com.algorand.algosdk.v2.client.common.Query;
+import com.algorand.algosdk.v2.client.common.QueryData;
+import com.algorand.algosdk.v2.client.common.Response;
+import com.algorand.algosdk.v2.client.model.LedgerStateDelta;
+
+
+/**
+ * Get ledger deltas for a round.
+ * /v2/deltas/{round}
+ */
+public class GetLedgerStateDelta extends Query {
+
+ private Long round;
+
+ /**
+ * @param round The round for which the deltas are desired.
+ */
+ public GetLedgerStateDelta(Client client, Long round) {
+ super(client, new HttpMethod("get"));
+ addQuery("format", "msgpack");
+ this.round = round;
+ }
+
+ /**
+ * Execute the query.
+ * @return the query response object.
+ * @throws Exception
+ */
+ @Override
+ public Response execute() throws Exception {
+ Response resp = baseExecute();
+ resp.setValueType(LedgerStateDelta.class);
+ return resp;
+ }
+
+ /**
+ * Execute the query with custom headers, there must be an equal number of keys and values
+ * or else an error will be generated.
+ * @param headers an array of header keys
+ * @param values an array of header values
+ * @return the query response object.
+ * @throws Exception
+ */
+ @Override
+ public Response execute(String[] headers, String[] values) throws Exception {
+ Response resp = baseExecute(headers, values);
+ resp.setValueType(LedgerStateDelta.class);
+ return resp;
+ }
+
+ protected QueryData getRequestString() {
+ if (this.round == null) {
+ throw new RuntimeException("round is not set. It is a required parameter.");
+ }
+ addPathSegment(String.valueOf("v2"));
+ addPathSegment(String.valueOf("deltas"));
+ addPathSegment(String.valueOf(round));
+
+ return qd;
+ }
+}
diff --git a/src/main/java/com/algorand/algosdk/v2/client/algod/GetLedgerStateDeltaForTransactionGroup.java b/src/main/java/com/algorand/algosdk/v2/client/algod/GetLedgerStateDeltaForTransactionGroup.java
new file mode 100644
index 000000000..2f47e1b9e
--- /dev/null
+++ b/src/main/java/com/algorand/algosdk/v2/client/algod/GetLedgerStateDeltaForTransactionGroup.java
@@ -0,0 +1,67 @@
+package com.algorand.algosdk.v2.client.algod;
+
+import com.algorand.algosdk.v2.client.common.Client;
+import com.algorand.algosdk.v2.client.common.HttpMethod;
+import com.algorand.algosdk.v2.client.common.Query;
+import com.algorand.algosdk.v2.client.common.QueryData;
+import com.algorand.algosdk.v2.client.common.Response;
+import com.algorand.algosdk.v2.client.model.LedgerStateDelta;
+
+
+/**
+ * Get a ledger delta for a given transaction group.
+ * /v2/deltas/txn/group/{id}
+ */
+public class GetLedgerStateDeltaForTransactionGroup extends Query {
+
+ private String id;
+
+ /**
+ * @param id A transaction ID, or transaction group ID
+ */
+ public GetLedgerStateDeltaForTransactionGroup(Client client, String id) {
+ super(client, new HttpMethod("get"));
+ addQuery("format", "msgpack");
+ this.id = id;
+ }
+
+ /**
+ * Execute the query.
+ * @return the query response object.
+ * @throws Exception
+ */
+ @Override
+ public Response execute() throws Exception {
+ Response resp = baseExecute();
+ resp.setValueType(LedgerStateDelta.class);
+ return resp;
+ }
+
+ /**
+ * Execute the query with custom headers, there must be an equal number of keys and values
+ * or else an error will be generated.
+ * @param headers an array of header keys
+ * @param values an array of header values
+ * @return the query response object.
+ * @throws Exception
+ */
+ @Override
+ public Response execute(String[] headers, String[] values) throws Exception {
+ Response resp = baseExecute(headers, values);
+ resp.setValueType(LedgerStateDelta.class);
+ return resp;
+ }
+
+ protected QueryData getRequestString() {
+ if (this.id == null) {
+ throw new RuntimeException("id is not set. It is a required parameter.");
+ }
+ addPathSegment(String.valueOf("v2"));
+ addPathSegment(String.valueOf("deltas"));
+ addPathSegment(String.valueOf("txn"));
+ addPathSegment(String.valueOf("group"));
+ addPathSegment(String.valueOf(id));
+
+ return qd;
+ }
+}
diff --git a/src/main/java/com/algorand/algosdk/v2/client/algod/GetTransactionGroupLedgerStateDeltasForRound.java b/src/main/java/com/algorand/algosdk/v2/client/algod/GetTransactionGroupLedgerStateDeltasForRound.java
new file mode 100644
index 000000000..204e72f35
--- /dev/null
+++ b/src/main/java/com/algorand/algosdk/v2/client/algod/GetTransactionGroupLedgerStateDeltasForRound.java
@@ -0,0 +1,67 @@
+package com.algorand.algosdk.v2.client.algod;
+
+import com.algorand.algosdk.v2.client.common.Client;
+import com.algorand.algosdk.v2.client.common.HttpMethod;
+import com.algorand.algosdk.v2.client.common.Query;
+import com.algorand.algosdk.v2.client.common.QueryData;
+import com.algorand.algosdk.v2.client.common.Response;
+import com.algorand.algosdk.v2.client.model.TransactionGroupLedgerStateDeltasForRoundResponse;
+
+
+/**
+ * Get ledger deltas for transaction groups in a given round.
+ * /v2/deltas/{round}/txn/group
+ */
+public class GetTransactionGroupLedgerStateDeltasForRound extends Query {
+
+ private Long round;
+
+ /**
+ * @param round The round for which the deltas are desired.
+ */
+ public GetTransactionGroupLedgerStateDeltasForRound(Client client, Long round) {
+ super(client, new HttpMethod("get"));
+ addQuery("format", "msgpack");
+ this.round = round;
+ }
+
+ /**
+ * Execute the query.
+ * @return the query response object.
+ * @throws Exception
+ */
+ @Override
+ public Response execute() throws Exception {
+ Response resp = baseExecute();
+ resp.setValueType(TransactionGroupLedgerStateDeltasForRoundResponse.class);
+ return resp;
+ }
+
+ /**
+ * Execute the query with custom headers, there must be an equal number of keys and values
+ * or else an error will be generated.
+ * @param headers an array of header keys
+ * @param values an array of header values
+ * @return the query response object.
+ * @throws Exception
+ */
+ @Override
+ public Response execute(String[] headers, String[] values) throws Exception {
+ Response resp = baseExecute(headers, values);
+ resp.setValueType(TransactionGroupLedgerStateDeltasForRoundResponse.class);
+ return resp;
+ }
+
+ protected QueryData getRequestString() {
+ if (this.round == null) {
+ throw new RuntimeException("round is not set. It is a required parameter.");
+ }
+ addPathSegment(String.valueOf("v2"));
+ addPathSegment(String.valueOf("deltas"));
+ addPathSegment(String.valueOf(round));
+ addPathSegment(String.valueOf("txn"));
+ addPathSegment(String.valueOf("group"));
+
+ return qd;
+ }
+}
diff --git a/src/main/java/com/algorand/algosdk/v2/client/common/AlgodClient.java b/src/main/java/com/algorand/algosdk/v2/client/common/AlgodClient.java
index 84fd4fd29..08f90299c 100644
--- a/src/main/java/com/algorand/algosdk/v2/client/common/AlgodClient.java
+++ b/src/main/java/com/algorand/algosdk/v2/client/common/AlgodClient.java
@@ -21,6 +21,9 @@
import com.algorand.algosdk.v2.client.algod.TransactionParams;
import com.algorand.algosdk.v2.client.algod.GetPendingTransactions;
import com.algorand.algosdk.v2.client.algod.PendingTransactionInformation;
+import com.algorand.algosdk.v2.client.algod.GetLedgerStateDelta;
+import com.algorand.algosdk.v2.client.algod.GetTransactionGroupLedgerStateDeltasForRound;
+import com.algorand.algosdk.v2.client.algod.GetLedgerStateDeltaForTransactionGroup;
import com.algorand.algosdk.v2.client.algod.GetStateProof;
import com.algorand.algosdk.v2.client.algod.GetLightBlockHeaderProof;
import com.algorand.algosdk.v2.client.algod.GetApplicationByID;
@@ -251,6 +254,30 @@ public PendingTransactionInformation PendingTransactionInformation(String txid)
return new PendingTransactionInformation((Client) this, txid);
}
+ /**
+ * Get ledger deltas for a round.
+ * /v2/deltas/{round}
+ */
+ public GetLedgerStateDelta GetLedgerStateDelta(Long round) {
+ return new GetLedgerStateDelta((Client) this, round);
+ }
+
+ /**
+ * Get ledger deltas for transaction groups in a given round.
+ * /v2/deltas/{round}/txn/group
+ */
+ public GetTransactionGroupLedgerStateDeltasForRound GetTransactionGroupLedgerStateDeltasForRound(Long round) {
+ return new GetTransactionGroupLedgerStateDeltasForRound((Client) this, round);
+ }
+
+ /**
+ * Get a ledger delta for a given transaction group.
+ * /v2/deltas/txn/group/{id}
+ */
+ public GetLedgerStateDeltaForTransactionGroup GetLedgerStateDeltaForTransactionGroup(String id) {
+ return new GetLedgerStateDeltaForTransactionGroup((Client) this, id);
+ }
+
/**
* Get a state proof that covers a given round
* /v2/stateproofs/{round}
@@ -287,8 +314,8 @@ public GetApplicationBoxes GetApplicationBoxes(Long applicationId) {
}
/**
- * Given an application ID and box name, it returns the box name and value (each
- * base64 encoded). Box names must be in the goal app call arg encoding form
+ * Given an application ID and box name, it returns the round, box name, and value
+ * (each base64 encoded). Box names must be in the goal app call arg encoding form
* 'encoding:value'. For ints, use the form 'int:1234'. For raw bytes, use the form
* 'b64:A=='. For printable strings, use the form 'str:hello'. For addresses, use
* the form 'addr:XYZ...'.
diff --git a/src/main/java/com/algorand/algosdk/v2/client/model/Box.java b/src/main/java/com/algorand/algosdk/v2/client/model/Box.java
index 326593c4a..3498ceedf 100644
--- a/src/main/java/com/algorand/algosdk/v2/client/model/Box.java
+++ b/src/main/java/com/algorand/algosdk/v2/client/model/Box.java
@@ -23,6 +23,12 @@ public String name() {
}
public byte[] name;
+ /**
+ * The round for which this information is relevant
+ */
+ @JsonProperty("round")
+ public Long round;
+
/**
* (value) box value, base64 encoded.
*/
@@ -43,6 +49,7 @@ public boolean equals(Object o) {
Box other = (Box) o;
if (!Objects.deepEquals(this.name, other.name)) return false;
+ if (!Objects.deepEquals(this.round, other.round)) return false;
if (!Objects.deepEquals(this.value, other.value)) return false;
return true;
diff --git a/src/main/java/com/algorand/algosdk/v2/client/model/LedgerStateDelta.java b/src/main/java/com/algorand/algosdk/v2/client/model/LedgerStateDelta.java
new file mode 100644
index 000000000..2f14c35f9
--- /dev/null
+++ b/src/main/java/com/algorand/algosdk/v2/client/model/LedgerStateDelta.java
@@ -0,0 +1,8 @@
+package com.algorand.algosdk.v2.client.model;
+
+import java.util.HashMap;
+
+/**
+ * Contains a ledger delta
+ */
+public class LedgerStateDelta extends HashMap {}
diff --git a/src/main/java/com/algorand/algosdk/v2/client/model/LedgerStateDeltaForTransactionGroup.java b/src/main/java/com/algorand/algosdk/v2/client/model/LedgerStateDeltaForTransactionGroup.java
new file mode 100644
index 000000000..cb518baab
--- /dev/null
+++ b/src/main/java/com/algorand/algosdk/v2/client/model/LedgerStateDeltaForTransactionGroup.java
@@ -0,0 +1,37 @@
+package com.algorand.algosdk.v2.client.model;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Objects;
+
+import com.algorand.algosdk.v2.client.common.PathResponse;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Contains a ledger delta for a single transaction group
+ */
+public class LedgerStateDeltaForTransactionGroup extends PathResponse {
+
+ /**
+ * Ledger StateDelta object
+ */
+ @JsonProperty("Delta")
+ public HashMap delta;
+
+ @JsonProperty("Ids")
+ public List ids = new ArrayList();
+
+ @Override
+ public boolean equals(Object o) {
+
+ if (this == o) return true;
+ if (o == null) return false;
+
+ LedgerStateDeltaForTransactionGroup other = (LedgerStateDeltaForTransactionGroup) o;
+ if (!Objects.deepEquals(this.delta, other.delta)) return false;
+ if (!Objects.deepEquals(this.ids, other.ids)) return false;
+
+ return true;
+ }
+}
diff --git a/src/main/java/com/algorand/algosdk/v2/client/model/SimulateRequest.java b/src/main/java/com/algorand/algosdk/v2/client/model/SimulateRequest.java
index d11447cc5..68b69bed1 100644
--- a/src/main/java/com/algorand/algosdk/v2/client/model/SimulateRequest.java
+++ b/src/main/java/com/algorand/algosdk/v2/client/model/SimulateRequest.java
@@ -25,6 +25,18 @@ public class SimulateRequest extends PathResponse {
@JsonProperty("allow-more-logging")
public Boolean allowMoreLogging;
+ /**
+ * An object that configures simulation execution trace.
+ */
+ @JsonProperty("exec-trace-config")
+ public SimulateTraceConfig execTraceConfig;
+
+ /**
+ * Applies extra opcode budget during simulation for each transaction group.
+ */
+ @JsonProperty("extra-opcode-budget")
+ public Long extraOpcodeBudget;
+
/**
* The transaction groups to simulate.
*/
@@ -40,6 +52,8 @@ public boolean equals(Object o) {
SimulateRequest other = (SimulateRequest) o;
if (!Objects.deepEquals(this.allowEmptySignatures, other.allowEmptySignatures)) return false;
if (!Objects.deepEquals(this.allowMoreLogging, other.allowMoreLogging)) return false;
+ if (!Objects.deepEquals(this.execTraceConfig, other.execTraceConfig)) return false;
+ if (!Objects.deepEquals(this.extraOpcodeBudget, other.extraOpcodeBudget)) return false;
if (!Objects.deepEquals(this.txnGroups, other.txnGroups)) return false;
return true;
diff --git a/src/main/java/com/algorand/algosdk/v2/client/model/SimulateResponse.java b/src/main/java/com/algorand/algosdk/v2/client/model/SimulateResponse.java
index 213713d35..0dad12b91 100644
--- a/src/main/java/com/algorand/algosdk/v2/client/model/SimulateResponse.java
+++ b/src/main/java/com/algorand/algosdk/v2/client/model/SimulateResponse.java
@@ -20,6 +20,12 @@ public class SimulateResponse extends PathResponse {
@JsonProperty("eval-overrides")
public SimulationEvalOverrides evalOverrides;
+ /**
+ * An object that configures simulation execution trace.
+ */
+ @JsonProperty("exec-trace-config")
+ public SimulateTraceConfig execTraceConfig;
+
/**
* The round immediately preceding this simulation. State changes through this
* round were used to run this simulation.
@@ -47,6 +53,7 @@ public boolean equals(Object o) {
SimulateResponse other = (SimulateResponse) o;
if (!Objects.deepEquals(this.evalOverrides, other.evalOverrides)) return false;
+ if (!Objects.deepEquals(this.execTraceConfig, other.execTraceConfig)) return false;
if (!Objects.deepEquals(this.lastRound, other.lastRound)) return false;
if (!Objects.deepEquals(this.txnGroups, other.txnGroups)) return false;
if (!Objects.deepEquals(this.version, other.version)) return false;
diff --git a/src/main/java/com/algorand/algosdk/v2/client/model/SimulateTraceConfig.java b/src/main/java/com/algorand/algosdk/v2/client/model/SimulateTraceConfig.java
new file mode 100644
index 000000000..9e7266810
--- /dev/null
+++ b/src/main/java/com/algorand/algosdk/v2/client/model/SimulateTraceConfig.java
@@ -0,0 +1,30 @@
+package com.algorand.algosdk.v2.client.model;
+
+import java.util.Objects;
+
+import com.algorand.algosdk.v2.client.common.PathResponse;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * An object that configures simulation execution trace.
+ */
+public class SimulateTraceConfig extends PathResponse {
+
+ /**
+ * A boolean option for opting in execution trace features simulation endpoint.
+ */
+ @JsonProperty("enable")
+ public Boolean enable;
+
+ @Override
+ public boolean equals(Object o) {
+
+ if (this == o) return true;
+ if (o == null) return false;
+
+ SimulateTraceConfig other = (SimulateTraceConfig) o;
+ if (!Objects.deepEquals(this.enable, other.enable)) return false;
+
+ return true;
+ }
+}
diff --git a/src/main/java/com/algorand/algosdk/v2/client/model/SimulateTransactionResult.java b/src/main/java/com/algorand/algosdk/v2/client/model/SimulateTransactionResult.java
index 783cb6435..280084656 100644
--- a/src/main/java/com/algorand/algosdk/v2/client/model/SimulateTransactionResult.java
+++ b/src/main/java/com/algorand/algosdk/v2/client/model/SimulateTransactionResult.java
@@ -17,6 +17,13 @@ public class SimulateTransactionResult extends PathResponse {
@JsonProperty("app-budget-consumed")
public Long appBudgetConsumed;
+ /**
+ * The execution trace of calling an app or a logic sig, containing the inner app
+ * call trace in a recursive way.
+ */
+ @JsonProperty("exec-trace")
+ public SimulationTransactionExecTrace execTrace;
+
/**
* Budget used during execution of a logic sig transaction.
*/
@@ -38,6 +45,7 @@ public boolean equals(Object o) {
SimulateTransactionResult other = (SimulateTransactionResult) o;
if (!Objects.deepEquals(this.appBudgetConsumed, other.appBudgetConsumed)) return false;
+ if (!Objects.deepEquals(this.execTrace, other.execTrace)) return false;
if (!Objects.deepEquals(this.logicSigBudgetConsumed, other.logicSigBudgetConsumed)) return false;
if (!Objects.deepEquals(this.txnResult, other.txnResult)) return false;
diff --git a/src/main/java/com/algorand/algosdk/v2/client/model/SimulationEvalOverrides.java b/src/main/java/com/algorand/algosdk/v2/client/model/SimulationEvalOverrides.java
index 7737596b6..26b533b53 100644
--- a/src/main/java/com/algorand/algosdk/v2/client/model/SimulationEvalOverrides.java
+++ b/src/main/java/com/algorand/algosdk/v2/client/model/SimulationEvalOverrides.java
@@ -19,17 +19,23 @@ public class SimulationEvalOverrides extends PathResponse {
@JsonProperty("allow-empty-signatures")
public Boolean allowEmptySignatures;
+ /**
+ * The extra opcode budget added to each transaction group during simulation
+ */
+ @JsonProperty("extra-opcode-budget")
+ public Long extraOpcodeBudget;
+
/**
* The maximum log calls one can make during simulation
*/
@JsonProperty("max-log-calls")
- public java.math.BigInteger maxLogCalls;
+ public Long maxLogCalls;
/**
* The maximum byte number to log during simulation
*/
@JsonProperty("max-log-size")
- public java.math.BigInteger maxLogSize;
+ public Long maxLogSize;
@Override
public boolean equals(Object o) {
@@ -39,6 +45,7 @@ public boolean equals(Object o) {
SimulationEvalOverrides other = (SimulationEvalOverrides) o;
if (!Objects.deepEquals(this.allowEmptySignatures, other.allowEmptySignatures)) return false;
+ if (!Objects.deepEquals(this.extraOpcodeBudget, other.extraOpcodeBudget)) return false;
if (!Objects.deepEquals(this.maxLogCalls, other.maxLogCalls)) return false;
if (!Objects.deepEquals(this.maxLogSize, other.maxLogSize)) return false;
diff --git a/src/main/java/com/algorand/algosdk/v2/client/model/SimulationOpcodeTraceUnit.java b/src/main/java/com/algorand/algosdk/v2/client/model/SimulationOpcodeTraceUnit.java
new file mode 100644
index 000000000..609b808cd
--- /dev/null
+++ b/src/main/java/com/algorand/algosdk/v2/client/model/SimulationOpcodeTraceUnit.java
@@ -0,0 +1,39 @@
+package com.algorand.algosdk.v2.client.model;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+import com.algorand.algosdk.v2.client.common.PathResponse;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * The set of trace information and effect from evaluating a single opcode.
+ */
+public class SimulationOpcodeTraceUnit extends PathResponse {
+
+ /**
+ * The program counter of the current opcode being evaluated.
+ */
+ @JsonProperty("pc")
+ public Long pc;
+
+ /**
+ * The indexes of the traces for inner transactions spawned by this opcode, if any.
+ */
+ @JsonProperty("spawned-inners")
+ public List spawnedInners = new ArrayList();
+
+ @Override
+ public boolean equals(Object o) {
+
+ if (this == o) return true;
+ if (o == null) return false;
+
+ SimulationOpcodeTraceUnit other = (SimulationOpcodeTraceUnit) o;
+ if (!Objects.deepEquals(this.pc, other.pc)) return false;
+ if (!Objects.deepEquals(this.spawnedInners, other.spawnedInners)) return false;
+
+ return true;
+ }
+}
diff --git a/src/main/java/com/algorand/algosdk/v2/client/model/SimulationTransactionExecTrace.java b/src/main/java/com/algorand/algosdk/v2/client/model/SimulationTransactionExecTrace.java
new file mode 100644
index 000000000..71219959d
--- /dev/null
+++ b/src/main/java/com/algorand/algosdk/v2/client/model/SimulationTransactionExecTrace.java
@@ -0,0 +1,55 @@
+package com.algorand.algosdk.v2.client.model;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+import com.algorand.algosdk.v2.client.common.PathResponse;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * The execution trace of calling an app or a logic sig, containing the inner app
+ * call trace in a recursive way.
+ */
+public class SimulationTransactionExecTrace extends PathResponse {
+
+ /**
+ * Program trace that contains a trace of opcode effects in an approval program.
+ */
+ @JsonProperty("approval-program-trace")
+ public List approvalProgramTrace = new ArrayList();
+
+ /**
+ * Program trace that contains a trace of opcode effects in a clear state program.
+ */
+ @JsonProperty("clear-state-program-trace")
+ public List clearStateProgramTrace = new ArrayList();
+
+ /**
+ * An array of SimulationTransactionExecTrace representing the execution trace of
+ * any inner transactions executed.
+ */
+ @JsonProperty("inner-trace")
+ public List innerTrace = new ArrayList();
+
+ /**
+ * Program trace that contains a trace of opcode effects in a logic sig.
+ */
+ @JsonProperty("logic-sig-trace")
+ public List logicSigTrace = new ArrayList();
+
+ @Override
+ public boolean equals(Object o) {
+
+ if (this == o) return true;
+ if (o == null) return false;
+
+ SimulationTransactionExecTrace other = (SimulationTransactionExecTrace) o;
+ if (!Objects.deepEquals(this.approvalProgramTrace, other.approvalProgramTrace)) return false;
+ if (!Objects.deepEquals(this.clearStateProgramTrace, other.clearStateProgramTrace)) return false;
+ if (!Objects.deepEquals(this.innerTrace, other.innerTrace)) return false;
+ if (!Objects.deepEquals(this.logicSigTrace, other.logicSigTrace)) return false;
+
+ return true;
+ }
+}
diff --git a/src/main/java/com/algorand/algosdk/v2/client/model/TransactionAssetTransfer.java b/src/main/java/com/algorand/algosdk/v2/client/model/TransactionAssetTransfer.java
index 5480bf5b1..003b26c67 100644
--- a/src/main/java/com/algorand/algosdk/v2/client/model/TransactionAssetTransfer.java
+++ b/src/main/java/com/algorand/algosdk/v2/client/model/TransactionAssetTransfer.java
@@ -26,7 +26,7 @@ public class TransactionAssetTransfer extends PathResponse {
public Long assetId;
/**
- * Number of assets transfered to the close-to account as part of the transaction.
+ * Number of assets transferred to the close-to account as part of the transaction.
*/
@JsonProperty("close-amount")
public java.math.BigInteger closeAmount;
diff --git a/src/main/java/com/algorand/algosdk/v2/client/model/TransactionGroupLedgerStateDeltasForRoundResponse.java b/src/main/java/com/algorand/algosdk/v2/client/model/TransactionGroupLedgerStateDeltasForRoundResponse.java
new file mode 100644
index 000000000..4d4cf6596
--- /dev/null
+++ b/src/main/java/com/algorand/algosdk/v2/client/model/TransactionGroupLedgerStateDeltasForRoundResponse.java
@@ -0,0 +1,30 @@
+package com.algorand.algosdk.v2.client.model;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+import com.algorand.algosdk.v2.client.common.PathResponse;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Response containing all ledger state deltas for transaction groups, with their
+ * associated Ids, in a single round.
+ */
+public class TransactionGroupLedgerStateDeltasForRoundResponse extends PathResponse {
+
+ @JsonProperty("Deltas")
+ public List deltas = new ArrayList();
+
+ @Override
+ public boolean equals(Object o) {
+
+ if (this == o) return true;
+ if (o == null) return false;
+
+ TransactionGroupLedgerStateDeltasForRoundResponse other = (TransactionGroupLedgerStateDeltasForRoundResponse) o;
+ if (!Objects.deepEquals(this.deltas, other.deltas)) return false;
+
+ return true;
+ }
+}
diff --git a/src/test/java/com/algorand/algosdk/unit/AlgodPaths.java b/src/test/java/com/algorand/algosdk/unit/AlgodPaths.java
index d3cae8855..2acfb34d9 100644
--- a/src/test/java/com/algorand/algosdk/unit/AlgodPaths.java
+++ b/src/test/java/com/algorand/algosdk/unit/AlgodPaths.java
@@ -151,4 +151,19 @@ public void getBlockTimestampOffset() {
public void setBlockTimestampOffset(Long round) {
ps.q = algodClient.SetBlockTimeStampOffset(round);
}
+
+ @When("we make a GetLedgerStateDelta call against round {long}")
+ public void we_make_a_get_ledger_state_delta_call_against_round(Long round) {
+ ps.q = algodClient.GetLedgerStateDelta(round);
+ }
+
+ @When("we make a LedgerStateDeltaForTransactionGroupResponse call for ID {string}")
+ public void we_make_a_ledger_state_delta_for_transaction_group_response_call_for_id(String id) {
+ ps.q = algodClient.GetLedgerStateDeltaForTransactionGroup(id);
+ }
+
+ @When("we make a TransactionGroupLedgerStateDeltaForRoundResponse call for round {long}")
+ public void we_make_a_transaction_group_ledger_state_delta_for_round_response_call_for_round(Long round) {
+ ps.q = algodClient.GetTransactionGroupLedgerStateDeltasForRound(round);
+ }
}
diff --git a/src/test/java/com/algorand/algosdk/unit/ResponsesShared.java b/src/test/java/com/algorand/algosdk/unit/ResponsesShared.java
index 40ce9e9bb..1b208117e 100644
--- a/src/test/java/com/algorand/algosdk/unit/ResponsesShared.java
+++ b/src/test/java/com/algorand/algosdk/unit/ResponsesShared.java
@@ -200,6 +200,15 @@ public void we_make_any_call_to(String client, String endpoint) throws Exception
case "GetSyncRound":
response = algod.GetSyncRound().execute();
break;
+ case "GetTransactionGroupLedgerStateDeltaForRound":
+ response = algod.GetTransactionGroupLedgerStateDeltasForRound(1234L).execute();
+ break;
+ case "GetLedgerStateDeltaForTransactionGroup":
+ response = algod.GetLedgerStateDeltaForTransactionGroup("abc123").execute();
+ break;
+ case "GetLedgerStateDelta":
+ response = algod.GetLedgerStateDelta(1234L).execute();
+ break;
default:
Assertions.fail("Unsupported algod endpoint: " + endpoint);
}
diff --git a/src/test/unit.tags b/src/test/unit.tags
index 720e9743e..820f7edf2 100644
--- a/src/test/unit.tags
+++ b/src/test/unit.tags
@@ -22,10 +22,13 @@
@unit.responses.blocksummary
@unit.responses.messagepack
@unit.responses.messagepack.231
+@unit.responses.statedelta
@unit.responses.timestamp
+@unit.responses.txngroupdeltas
@unit.responses.sync
@unit.responses.unlimited_assets
@unit.sourcemap
+@unit.statedelta
@unit.stateproof.paths
@unit.stateproof.responses
@unit.stateproof.responses.msgp
@@ -35,3 +38,4 @@
@unit.transactions
@unit.transactions.keyreg
@unit.transactions.payment
+@unit.txngroupdeltas
\ No newline at end of file