diff --git a/.circleci/config.yml b/.circleci/config.yml index 99d0dddd8..81c7a0a09 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -82,6 +82,7 @@ jobs: command: | export SUDO=sudo $SUDO apt update + if [ "<< parameters.browser >>" == "chrome" ]; then $SUDO apt -y install google-chrome-stable; else echo "skipping chrome install" ; fi $SUDO apt -y install ca-certificates curl gnupg lsb-release $SUDO curl -fsSL https://download.docker.com/linux/ubuntu/gpg | $SUDO gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg $SUDO echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \ @@ -123,7 +124,7 @@ commands: - run: name: Install Dependencies command: | - << parameters.sudo >> apt -y update && << parameters.sudo >> apt -y upgrade + << parameters.sudo >> apt -y update << parameters.sudo >> apt -y install curl make git build-essential jq unzip - node/install: node-version: '12' @@ -132,3 +133,4 @@ commands: command: | set -e npm ci + npm install chromedriver@latest diff --git a/CHANGELOG.md b/CHANGELOG.md index 4812b28c9..10f42ca44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +# v1.16.0 + +## Added + +- Dryrun stack printer +- Document more Indexer methods + +## Fixed + +- Corrected type of KMD keys +- Include foreign app addr in dryrun requests + # v1.15.0 ## Added diff --git a/Makefile b/Makefile index 07c7f82a4..888c0ed8c 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,6 @@ unit: - node_modules/.bin/cucumber-js --tags "@unit.offline or @unit.algod or @unit.indexer or @unit.rekey or @unit.tealsign or @unit.dryrun or @unit.applications or @unit.responses or @unit.transactions or @unit.transactions.keyreg or @unit.transactions.payment or @unit.responses.231 or @unit.feetest or @unit.indexer.logs or @unit.abijson or @unit.atomic_transaction_composer or @unit.responses.unlimited_assets or @unit.indexer.ledger_refactoring or @unit.algod.ledger_refactoring" tests/cucumber/features --require-module ts-node/register --require tests/cucumber/steps/index.js + node_modules/.bin/cucumber-js --tags "@unit.offline or @unit.algod or @unit.indexer or @unit.rekey or @unit.tealsign or @unit.dryrun or @unit.applications or @unit.responses or @unit.transactions or @unit.transactions.keyreg or @unit.transactions.payment or @unit.responses.231 or @unit.feetest or @unit.indexer.logs or @unit.abijson or @unit.atomic_transaction_composer or @unit.responses.unlimited_assets or @unit.indexer.ledger_refactoring or @unit.algod.ledger_refactoring or @unit.dryrun.trace.application" tests/cucumber/features --require-module ts-node/register --require tests/cucumber/steps/index.js + integration: node_modules/.bin/cucumber-js --tags "@algod or @assets or @auction or @kmd or @send or @indexer or @rekey or @send.keyregtxn or @dryrun or @compile or @applications or @indexer.applications or @applications.verified or @indexer.231 or @abi or @c2c" tests/cucumber/features --require-module ts-node/register --require tests/cucumber/steps/index.js diff --git a/README.md b/README.md index 3a21b4134..a908a41db 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,8 @@ Include a minified browser bundle directly in your HTML like so: ```html ``` @@ -32,8 +32,8 @@ or ```html ``` diff --git a/package-lock.json b/package-lock.json index 27f8775c7..1fc3cb632 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "algosdk", - "version": "1.15.0", + "version": "1.16.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "algosdk", - "version": "1.15.0", + "version": "1.16.0", "license": "MIT", "dependencies": { "algo-msgpack-with-bigint": "^2.1.1", @@ -28,7 +28,7 @@ "@typescript-eslint/eslint-plugin": "^4.26.1", "@typescript-eslint/parser": "^4.26.1", "assert": "^2.0.0", - "chromedriver": "^99.0.0", + "chromedriver": "^101.0.0", "concurrently": "^6.2.0", "coveralls": "^3.1.0", "cucumber": "^5.1.0", @@ -51,7 +51,7 @@ "source-map-loader": "^2.0.2", "ts-loader": "^8.3.0", "ts-node": "^10.0.0", - "typedoc": "^0.22.11", + "typedoc": "^0.22.13", "typedoc-plugin-missing-exports": "^0.22.6", "typedoc-plugin-rename-defaults": "^0.4.0", "typescript": "^4.2.3", @@ -1514,9 +1514,9 @@ } }, "node_modules/chromedriver": { - "version": "99.0.0", - "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-99.0.0.tgz", - "integrity": "sha512-pyB+5LuyZdb7EBPL3i5D5yucZUD+SlkdiUtmpjaEnLd9zAXp+SvD/hP5xF4l/ZmWvUo/1ZLxAI1YBdhazGTpgA==", + "version": "101.0.0", + "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-101.0.0.tgz", + "integrity": "sha512-LkkWxy6KM/0YdJS8qBeg5vfkTZTRamhBfOttb4oic4echDgWvCU1E8QcBbUBOHqZpSrYMyi7WMKmKMhXFUaZ+w==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -6597,9 +6597,9 @@ } }, "node_modules/shiki": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.10.0.tgz", - "integrity": "sha512-iczxaIYeBFHTFrQPb9DVy2SKgYxC4Wo7Iucm7C17cCh2Ge/refnvHscUOxM85u57MfLoNOtjoEFUWt9gBexblA==", + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.10.1.tgz", + "integrity": "sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==", "dev": true, "dependencies": { "jsonc-parser": "^3.0.0", @@ -7530,16 +7530,16 @@ } }, "node_modules/typedoc": { - "version": "0.22.11", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.11.tgz", - "integrity": "sha512-pVr3hh6dkS3lPPaZz1fNpvcrqLdtEvXmXayN55czlamSgvEjh+57GUqfhAI1Xsuu/hNHUT1KNSx8LH2wBP/7SA==", + "version": "0.22.13", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.13.tgz", + "integrity": "sha512-NHNI7Dr6JHa/I3+c62gdRNXBIyX7P33O9TafGLd07ur3MqzcKgwTvpg18EtvCLHJyfeSthAtCLpM7WkStUmDuQ==", "dev": true, "dependencies": { "glob": "^7.2.0", "lunr": "^2.3.9", - "marked": "^4.0.10", - "minimatch": "^3.0.4", - "shiki": "^0.10.0" + "marked": "^4.0.12", + "minimatch": "^5.0.1", + "shiki": "^0.10.1" }, "bin": { "typedoc": "bin/typedoc" @@ -7548,7 +7548,7 @@ "node": ">= 12.10.0" }, "peerDependencies": { - "typescript": "4.0.x || 4.1.x || 4.2.x || 4.3.x || 4.4.x || 4.5.x" + "typescript": "4.0.x || 4.1.x || 4.2.x || 4.3.x || 4.4.x || 4.5.x || 4.6.x" } }, "node_modules/typedoc-plugin-missing-exports": { @@ -7589,6 +7589,39 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/typedoc/node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/typedoc/node_modules/minimatch": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/typedoc/node_modules/minimatch/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, "node_modules/typescript": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", @@ -7752,9 +7785,9 @@ } }, "node_modules/vscode-oniguruma": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.6.1.tgz", - "integrity": "sha512-vc4WhSIaVpgJ0jJIejjYxPvURJavX6QG41vu0mGhqywMkQqulezEqEQ3cO3gc8GvcOpX6ycmKGqRoROEMBNXTQ==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.6.2.tgz", + "integrity": "sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA==", "dev": true }, "node_modules/vscode-textmate": { @@ -9478,9 +9511,9 @@ "dev": true }, "chromedriver": { - "version": "99.0.0", - "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-99.0.0.tgz", - "integrity": "sha512-pyB+5LuyZdb7EBPL3i5D5yucZUD+SlkdiUtmpjaEnLd9zAXp+SvD/hP5xF4l/ZmWvUo/1ZLxAI1YBdhazGTpgA==", + "version": "101.0.0", + "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-101.0.0.tgz", + "integrity": "sha512-LkkWxy6KM/0YdJS8qBeg5vfkTZTRamhBfOttb4oic4echDgWvCU1E8QcBbUBOHqZpSrYMyi7WMKmKMhXFUaZ+w==", "dev": true, "requires": { "@testim/chrome-version": "^1.1.2", @@ -13350,9 +13383,9 @@ "dev": true }, "shiki": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.10.0.tgz", - "integrity": "sha512-iczxaIYeBFHTFrQPb9DVy2SKgYxC4Wo7Iucm7C17cCh2Ge/refnvHscUOxM85u57MfLoNOtjoEFUWt9gBexblA==", + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.10.1.tgz", + "integrity": "sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==", "dev": true, "requires": { "jsonc-parser": "^3.0.0", @@ -14074,16 +14107,16 @@ } }, "typedoc": { - "version": "0.22.11", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.11.tgz", - "integrity": "sha512-pVr3hh6dkS3lPPaZz1fNpvcrqLdtEvXmXayN55czlamSgvEjh+57GUqfhAI1Xsuu/hNHUT1KNSx8LH2wBP/7SA==", + "version": "0.22.13", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.13.tgz", + "integrity": "sha512-NHNI7Dr6JHa/I3+c62gdRNXBIyX7P33O9TafGLd07ur3MqzcKgwTvpg18EtvCLHJyfeSthAtCLpM7WkStUmDuQ==", "dev": true, "requires": { "glob": "^7.2.0", "lunr": "^2.3.9", - "marked": "^4.0.10", - "minimatch": "^3.0.4", - "shiki": "^0.10.0" + "marked": "^4.0.12", + "minimatch": "^5.0.1", + "shiki": "^0.10.1" }, "dependencies": { "glob": { @@ -14098,6 +14131,37 @@ "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "minimatch": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + } } } } @@ -14250,9 +14314,9 @@ } }, "vscode-oniguruma": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.6.1.tgz", - "integrity": "sha512-vc4WhSIaVpgJ0jJIejjYxPvURJavX6QG41vu0mGhqywMkQqulezEqEQ3cO3gc8GvcOpX6ycmKGqRoROEMBNXTQ==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.6.2.tgz", + "integrity": "sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA==", "dev": true }, "vscode-textmate": { diff --git a/package.json b/package.json index ece58b792..571107834 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "algosdk", - "version": "1.15.0", + "version": "1.16.0", "description": "The official JavaScript SDK for Algorand", "main": "dist/cjs/index.js", "module": "dist/esm/index.js", @@ -36,7 +36,7 @@ "@typescript-eslint/eslint-plugin": "^4.26.1", "@typescript-eslint/parser": "^4.26.1", "assert": "^2.0.0", - "chromedriver": "^99.0.0", + "chromedriver": "^101.0.0", "concurrently": "^6.2.0", "coveralls": "^3.1.0", "cucumber": "^5.1.0", @@ -59,7 +59,7 @@ "source-map-loader": "^2.0.2", "ts-loader": "^8.3.0", "ts-node": "^10.0.0", - "typedoc": "^0.22.11", + "typedoc": "^0.22.13", "typedoc-plugin-missing-exports": "^0.22.6", "typedoc-plugin-rename-defaults": "^0.4.0", "typescript": "^4.2.3", @@ -72,6 +72,7 @@ "prepare-browser-tests": "npm run build && mkdir -p tests/cucumber/browser/build && cp dist/browser/algosdk.min.* tests/cucumber/browser/build/ && webpack --config tests/cucumber/browser/webpack.config.js", "build": "concurrently \"webpack --config webpack.config.js\" \"tsc -p tsconfig-esm.json\" \"tsc -p tsconfig-cjs.json\"", "docs": "typedoc src/main.ts --options typedoc.config.json", + "docs:dev": "typedoc src/main.ts --options typedoc.config.json --watch --preserveWatchOutput", "lint": "eslint .", "lint:fix": "eslint --fix .", "format": "prettier --write .", diff --git a/src/client/kmd.ts b/src/client/kmd.ts index 86f8884b4..b34a3dd97 100644 --- a/src/client/kmd.ts +++ b/src/client/kmd.ts @@ -42,7 +42,7 @@ export default class Kmd extends ServiceClient { async createWallet( walletName: string, walletPassword: string, - walletMDK = '', + walletMDK: Uint8Array = new Uint8Array(), walletDriverName = 'sqlite' ) { const req = { @@ -170,7 +170,7 @@ export default class Kmd extends ServiceClient { * @param walletHandle * @param secretKey */ - async importKey(walletHandle: string, secretKey: string) { + async importKey(walletHandle: string, secretKey: Uint8Array) { const req = { wallet_handle_token: walletHandle, private_key: Buffer.from(secretKey).toString('base64'), diff --git a/src/client/v2/indexer/indexer.ts b/src/client/v2/indexer/indexer.ts index 0257a64a7..ed90f7474 100644 --- a/src/client/v2/indexer/indexer.ts +++ b/src/client/v2/indexer/indexer.ts @@ -196,10 +196,10 @@ export default class IndexerClient extends ServiceClient { * #### Example * ```typescript * const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; - * const accountInfo = await indexerClient.lookupAccountAssets(address).do(); + * const accountAssets = await indexerClient.lookupAccountAssets(address).do(); * ``` * - * [Response data schema details](https://developer.algorand.org/docs/rest-apis/indexer/#get-v2accountsaccount-id) + * [Response data schema details](https://developer.algorand.org/docs/rest-apis/indexer/#get-v2accountsaccount-idassets) * @param account - The address of the account to look up. * @category GET */ @@ -213,10 +213,10 @@ export default class IndexerClient extends ServiceClient { * #### Example * ```typescript * const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; - * const accountInfo = await indexerClient.lookupAccountCreatedAssets(address).do(); + * const accountCreatedAssets = await indexerClient.lookupAccountCreatedAssets(address).do(); * ``` * - * [Response data schema details](https://developer.algorand.org/docs/rest-apis/indexer/#get-v2accountsaccount-id) + * [Response data schema details](https://developer.algorand.org/docs/rest-apis/indexer/#get-v2accountsaccount-idcreated-assets) * @param account - The address of the account to look up. * @category GET */ @@ -230,10 +230,10 @@ export default class IndexerClient extends ServiceClient { * #### Example * ```typescript * const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; - * const accountInfo = await indexerClient.lookupAccountAppLocalStates(address).do(); + * const accountAppLocalStates = await indexerClient.lookupAccountAppLocalStates(address).do(); * ``` * - * [Response data schema details](https://developer.algorand.org/docs/rest-apis/indexer/#get-v2accountsaccount-id) + * [Response data schema details](https://developer.algorand.org/docs/rest-apis/indexer/#get-v2accountsaccount-idapps-local-state) * @param account - The address of the account to look up. * @category GET */ @@ -247,10 +247,10 @@ export default class IndexerClient extends ServiceClient { * #### Example * ```typescript * const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; - * const accountInfo = await indexerClient.lookupAccountCreatedApplications(address).do(); + * const accountCreatedApps = await indexerClient.lookupAccountCreatedApplications(address).do(); * ``` * - * [Response data schema details](https://developer.algorand.org/docs/rest-apis/indexer/#get-v2accountsaccount-id) + * [Response data schema details](https://developer.algorand.org/docs/rest-apis/indexer/#get-v2accountsaccount-idcreated-applications) * @param account - The address of the account to look up. * @category GET */ diff --git a/src/client/v2/indexer/lookupAccountAppLocalStates.ts b/src/client/v2/indexer/lookupAccountAppLocalStates.ts index b434656e0..4a2c2da76 100644 --- a/src/client/v2/indexer/lookupAccountAppLocalStates.ts +++ b/src/client/v2/indexer/lookupAccountAppLocalStates.ts @@ -3,6 +3,19 @@ import HTTPClient from '../../client'; import IntDecoding from '../../../types/intDecoding'; export default class LookupAccountAppLocalStates extends JSONRequest { + /** + * Returns application local state about the given account. + * + * #### Example + * ```typescript + * const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; + * const accountAppLocalStates = await indexerClient.lookupAccountAppLocalStates(address).do(); + * ``` + * + * [Response data schema details](https://developer.algorand.org/docs/rest-apis/indexer/#get-v2accountsaccount-idapps-local-state) + * @param account - The address of the account to look up. + * @category GET + */ constructor( c: HTTPClient, intDecoding: IntDecoding, @@ -12,6 +25,9 @@ export default class LookupAccountAppLocalStates extends JSONRequest { this.account = account; } + /** + * @returns `/v2/accounts/${account}/apps-local-state` + */ path() { return `/v2/accounts/${this.account}/apps-local-state`; } @@ -30,6 +46,7 @@ export default class LookupAccountAppLocalStates extends JSONRequest { * ``` * * @param limit - maximum number of results to return. + * @category query */ limit(limit: number) { this.query.limit = limit; @@ -49,6 +66,7 @@ export default class LookupAccountAppLocalStates extends JSONRequest { * .do(); * ``` * @param round + * @category query */ round(round: number) { this.query.round = round; @@ -62,11 +80,16 @@ export default class LookupAccountAppLocalStates extends JSONRequest { * ```typescript * const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; * const maxResults = 20; - * const nextToken = "APA6C7C3NCANRPIBUWQOF7WSKLJMK6RPQUVFLLDV4U5WCQE4DEF26D4E3E"; - * const accountAssets = await indexerClient + * + * const accountAssetsPage1 = await indexerClient + * .lookupAccountAppLocalStates(address) + * .limit(maxResults) + * .do(); + * + * const accountAssetsPage2 = await indexerClient * .lookupAccountAppLocalStates(address) * .limit(maxResults) - * .next(nextToken) + * .next(accountAssetsPage1["next-token"]) * .do(); * ``` * @param nextToken - provided by the previous results. @@ -88,6 +111,7 @@ export default class LookupAccountAppLocalStates extends JSONRequest { * .do(); * ``` * @param value + * @category query */ includeAll(value = true) { this.query['include-all'] = value; @@ -95,7 +119,7 @@ export default class LookupAccountAppLocalStates extends JSONRequest { } /** - * Specify an applicationID to search for + * Specify an applicationID to search for. * * #### Example * ```typescript @@ -107,6 +131,7 @@ export default class LookupAccountAppLocalStates extends JSONRequest { * .do(); * ``` * @param index - the applicationID + * @category query */ applicationID(index: number) { this.query['application-id'] = index; diff --git a/src/client/v2/indexer/lookupAccountAssets.ts b/src/client/v2/indexer/lookupAccountAssets.ts index 5b56d615e..2d6194f4f 100644 --- a/src/client/v2/indexer/lookupAccountAssets.ts +++ b/src/client/v2/indexer/lookupAccountAssets.ts @@ -3,6 +3,19 @@ import HTTPClient from '../../client'; import IntDecoding from '../../../types/intDecoding'; export default class LookupAccountAssets extends JSONRequest { + /** + * Returns asset about the given account. + * + * #### Example + * ```typescript + * const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; + * const accountAssets = await indexerClient.lookupAccountAssets(address).do(); + * ``` + * + * [Response data schema details](https://developer.algorand.org/docs/rest-apis/indexer/#get-v2accountsaccount-idassets) + * @param account - The address of the account to look up. + * @category GET + */ constructor( c: HTTPClient, intDecoding: IntDecoding, @@ -12,6 +25,9 @@ export default class LookupAccountAssets extends JSONRequest { this.account = account; } + /** + * @returns `/v2/accounts/${account}/assets` + */ path() { return `/v2/accounts/${this.account}/assets`; } @@ -30,6 +46,7 @@ export default class LookupAccountAssets extends JSONRequest { * ``` * * @param limit - maximum number of results to return. + * @category query */ limit(limit: number) { this.query.limit = limit; @@ -49,6 +66,7 @@ export default class LookupAccountAssets extends JSONRequest { * .do(); * ``` * @param round + * @category query */ round(round: number) { this.query.round = round; @@ -62,14 +80,20 @@ export default class LookupAccountAssets extends JSONRequest { * ```typescript * const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; * const maxResults = 20; - * const nextToken = "APA6C7C3NCANRPIBUWQOF7WSKLJMK6RPQUVFLLDV4U5WCQE4DEF26D4E3E"; - * const accountAssets = await indexerClient + * + * const accountAssetsPage1 = await indexerClient + * .lookupAccountAssets(address) + * .limit(maxResults) + * .do(); + * + * const accountAssetsPage2 = await indexerClient * .lookupAccountAssets(address) * .limit(maxResults) - * .next(nextToken) + * .next(accountAssetsPage1["next-token"]) * .do(); * ``` * @param nextToken - provided by the previous results. + * @category query */ nextToken(nextToken: string) { this.query.next = nextToken; @@ -88,6 +112,7 @@ export default class LookupAccountAssets extends JSONRequest { * .do(); * ``` * @param value + * @category query */ includeAll(value = true) { this.query['include-all'] = value; @@ -107,6 +132,7 @@ export default class LookupAccountAssets extends JSONRequest { * .do(); * ``` * @param index - the assetID + * @category query */ assetId(index: number) { this.query['asset-id'] = index; diff --git a/src/client/v2/indexer/lookupAccountByID.ts b/src/client/v2/indexer/lookupAccountByID.ts index 0a03fb16c..8c024ec31 100644 --- a/src/client/v2/indexer/lookupAccountByID.ts +++ b/src/client/v2/indexer/lookupAccountByID.ts @@ -3,6 +3,19 @@ import HTTPClient from '../../client'; import IntDecoding from '../../../types/intDecoding'; export default class LookupAccountByID extends JSONRequest { + /** + * Returns information about the given account. + * + * #### Example + * ```typescript + * const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; + * const accountInfo = await indexerClient.lookupAccountByID(address).do(); + * ``` + * + * [Response data schema details](https://developer.algorand.org/docs/rest-apis/indexer/#get-v2accountsaccount-id) + * @param account - The address of the account to look up. + * @category GET + */ constructor( c: HTTPClient, intDecoding: IntDecoding, @@ -12,23 +25,83 @@ export default class LookupAccountByID extends JSONRequest { this.account = account; } + /** + * @returns `/v2/accounts/${account}` + */ path() { return `/v2/accounts/${this.account}`; } - // specific round to search + /** + * Specify round to filter with. + * + * #### Example + * ```typescript + * const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; + * const targetBlock = 18309917; + * const accountInfo = await indexerClient + * .lookupAccountByID(address) + * .round(targetBlock) + * .do(); + * ``` + * @param round + */ round(round: number) { this.query.round = round; return this; } - // include all items including closed accounts, deleted applications, destroyed assets, opted-out asset holdings, and closed-out application localstates + /** + * Include all items including closed accounts, deleted applications, destroyed assets, opted-out asset holdings, and closed-out application localstates. + * + * #### Example 1 + * ```typescript + * const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; + * const accountInfo = await indexerClient + * .lookupAccountByID(address) + * .includeAll(false) + * .do(); + * ``` + * + * #### Example 2 + * ```typescript + * const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; + * const accountInfo = await indexerClient + * .lookupAccountByID(address) + * .includeAll() + * .do(); + * ``` + * @param value + */ includeAll(value = true) { this.query['include-all'] = value; return this; } - // exclude + /** + * Exclude additional items such as asset holdings, application local data stored for this account, asset parameters created by this account, and application parameters created by this account. + * + * #### Example 1 + * ```typescript + * const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; + * const accountInfo = await indexerClient + * .lookupAccountByID(address) + * .exclude("all") + * .do(); + * ``` + * + * #### Example 2 + * ```typescript + * const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; + * const accountInfo = await indexerClient + * .lookupAccountByID(address) + * .exclude("assets,created-assets") + * .do(); + * ``` + * @remarks By default, it behaves as exclude=none + * @param exclude - Array of `all`, `assets`, `created-assets`, `apps-local-state`, `created-apps`, `none` + * @category query + */ exclude(exclude: string) { this.query.exclude = exclude; return this; diff --git a/src/client/v2/indexer/lookupAccountCreatedApplications.ts b/src/client/v2/indexer/lookupAccountCreatedApplications.ts index d93b90826..187ab3363 100644 --- a/src/client/v2/indexer/lookupAccountCreatedApplications.ts +++ b/src/client/v2/indexer/lookupAccountCreatedApplications.ts @@ -3,6 +3,19 @@ import HTTPClient from '../../client'; import IntDecoding from '../../../types/intDecoding'; export default class LookupAccountCreatedApplications extends JSONRequest { + /** + * Returns application information created by the given account. + * + * #### Example + * ```typescript + * const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; + * const accountCreatedApps = await indexerClient.lookupAccountCreatedApplications(address).do(); + * ``` + * + * [Response data schema details](https://developer.algorand.org/docs/rest-apis/indexer/#get-v2accountsaccount-idcreated-applications) + * @param account - The address of the account to look up. + * @category GET + */ constructor( c: HTTPClient, intDecoding: IntDecoding, @@ -12,6 +25,9 @@ export default class LookupAccountCreatedApplications extends JSONRequest { this.account = account; } + /** + * @returns `/v2/accounts/${account}/created-applications` + */ path() { return `/v2/accounts/${this.account}/created-applications`; } @@ -30,6 +46,7 @@ export default class LookupAccountCreatedApplications extends JSONRequest { * ``` * * @param limit - maximum number of results to return. + * @category query */ limit(limit: number) { this.query.limit = limit; @@ -49,6 +66,7 @@ export default class LookupAccountCreatedApplications extends JSONRequest { * .do(); * ``` * @param round + * @category query */ round(round: number) { this.query.round = round; @@ -62,14 +80,20 @@ export default class LookupAccountCreatedApplications extends JSONRequest { * ```typescript * const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; * const maxResults = 20; - * const nextToken = "APA6C7C3NCANRPIBUWQOF7WSKLJMK6RPQUVFLLDV4U5WCQE4DEF26D4E3E"; - * const accountAssets = await indexerClient + * + * const accountAssetsPage1 = await indexerClient + * .lookupAccountCreatedApplications(address) + * .limit(maxResults) + * .do(); + * + * const accountAssetsPage2 = await indexerClient * .lookupAccountCreatedApplications(address) * .limit(maxResults) - * .next(nextToken) + * .next(accountAssetsPage1["next-token"]) * .do(); * ``` * @param nextToken - provided by the previous results. + * @category query */ nextToken(nextToken: string) { this.query.next = nextToken; @@ -88,6 +112,7 @@ export default class LookupAccountCreatedApplications extends JSONRequest { * .do(); * ``` * @param value + * @category query */ includeAll(value = true) { this.query['include-all'] = value; @@ -95,7 +120,7 @@ export default class LookupAccountCreatedApplications extends JSONRequest { } /** - * Specify an applicationID to search for + * Specify an applicationID to search for. * * #### Example * ```typescript @@ -107,6 +132,7 @@ export default class LookupAccountCreatedApplications extends JSONRequest { * .do(); * ``` * @param index - the applicationID + * @category query */ applicationID(index: number) { this.query['application-id'] = index; diff --git a/src/client/v2/indexer/lookupAccountCreatedAssets.ts b/src/client/v2/indexer/lookupAccountCreatedAssets.ts index a27e3c778..f64a4e1e8 100644 --- a/src/client/v2/indexer/lookupAccountCreatedAssets.ts +++ b/src/client/v2/indexer/lookupAccountCreatedAssets.ts @@ -3,6 +3,19 @@ import HTTPClient from '../../client'; import IntDecoding from '../../../types/intDecoding'; export default class LookupAccountCreatedAssets extends JSONRequest { + /** + * Returns asset information created by the given account. + * + * #### Example + * ```typescript + * const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; + * const accountCreatedAssets = await indexerClient.lookupAccountCreatedAssets(address).do(); + * ``` + * + * [Response data schema details](https://developer.algorand.org/docs/rest-apis/indexer/#get-v2accountsaccount-idcreated-assets) + * @param account - The address of the account to look up. + * @category GET + */ constructor( c: HTTPClient, intDecoding: IntDecoding, @@ -12,6 +25,9 @@ export default class LookupAccountCreatedAssets extends JSONRequest { this.account = account; } + /** + * @returns `/v2/accounts/${account}/created-assets` + */ path() { return `/v2/accounts/${this.account}/created-assets`; } @@ -30,6 +46,7 @@ export default class LookupAccountCreatedAssets extends JSONRequest { * ``` * * @param limit - maximum number of results to return. + * @category query */ limit(limit: number) { this.query.limit = limit; @@ -49,6 +66,7 @@ export default class LookupAccountCreatedAssets extends JSONRequest { * .do(); * ``` * @param round + * @category query */ round(round: number) { this.query.round = round; @@ -62,14 +80,21 @@ export default class LookupAccountCreatedAssets extends JSONRequest { * ```typescript * const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; * const maxResults = 20; - * const nextToken = "APA6C7C3NCANRPIBUWQOF7WSKLJMK6RPQUVFLLDV4U5WCQE4DEF26D4E3E"; - * const accountAssets = await indexerClient + * + * const accountAssetsPage1 = await indexerClient + * .lookupAccountCreatedAssets(address) + * .limit(maxResults) + * .do(); + * ``` + * + * const accountAssetsPage2 = await indexerClient * .lookupAccountCreatedAssets(address) * .limit(maxResults) - * .next(nextToken) + * .next(accountAssetsPage1["next-token"]) * .do(); * ``` * @param nextToken - provided by the previous results. + * @category query */ nextToken(nextToken: string) { this.query.next = nextToken; @@ -88,6 +113,7 @@ export default class LookupAccountCreatedAssets extends JSONRequest { * .do(); * ``` * @param value + * @category query */ includeAll(value = true) { this.query['include-all'] = value; @@ -107,6 +133,7 @@ export default class LookupAccountCreatedAssets extends JSONRequest { * .do(); * ``` * @param index - the assetID + * @category query */ assetID(index: number) { this.query['asset-id'] = index; diff --git a/src/client/v2/indexer/lookupAccountTransactions.ts b/src/client/v2/indexer/lookupAccountTransactions.ts index 56c36b55e..69f41cd9b 100644 --- a/src/client/v2/indexer/lookupAccountTransactions.ts +++ b/src/client/v2/indexer/lookupAccountTransactions.ts @@ -37,14 +37,14 @@ export default class LookupAccountTransactions extends JSONRequest { } /** - * @returns /v2/accounts/`${account}`/transactions + * @returns `/v2/accounts/${account}/transactions` */ path() { return `/v2/accounts/${this.account}/transactions`; } /** - * Specifies a prefix which must be contained in the note field + * Specifies a prefix which must be contained in the note field. * * #### Example * ```typescript @@ -65,7 +65,7 @@ export default class LookupAccountTransactions extends JSONRequest { } /** - * Type of transaction to filter with + * Type of transaction to filter with. * * #### Example * ```typescript @@ -76,7 +76,7 @@ export default class LookupAccountTransactions extends JSONRequest { * .do(); * ``` * - * @param type - one of “pay”, “keyreg”, “acfg”, “axfer”, “afrz”, "appl" + * @param type - one of `pay`, `keyreg`, `acfg`, `axfer`, `afrz`, `appl` * @category query */ txType(type: string) { @@ -85,7 +85,7 @@ export default class LookupAccountTransactions extends JSONRequest { } /** - * Type of signature to filter with + * Type of signature to filter with. * - sig: Standard * - msig: MultiSig * - lsig: LogicSig @@ -99,7 +99,7 @@ export default class LookupAccountTransactions extends JSONRequest { * .do(); * ``` * - * @param type - one of “sig”, “msig”, “lsig” + * @param type - one of `sig`, `msig`, `lsig` * @category query */ sigType(type: string) { @@ -108,7 +108,7 @@ export default class LookupAccountTransactions extends JSONRequest { } /** - * Lookup the specific transaction by ID + * Lookup the specific transaction by ID. * * #### Example * ```typescript @@ -119,7 +119,7 @@ export default class LookupAccountTransactions extends JSONRequest { * .txid(txId) * .do(); * ``` - * + * @remarks Alternatively, use `indexerClient.lookupTransactionByID(txnId).do()` * @param txid * @category query */ @@ -129,7 +129,7 @@ export default class LookupAccountTransactions extends JSONRequest { } /** - * Include results for the specified round + * Include results for the specified round. * * #### Example * ```typescript @@ -150,7 +150,7 @@ export default class LookupAccountTransactions extends JSONRequest { } /** - * Include results at or after the specified min-round + * Include results at or after the specified min-round. * * #### Example * ```typescript @@ -171,7 +171,7 @@ export default class LookupAccountTransactions extends JSONRequest { } /** - * Include results at or before the specified max-round + * Include results at or before the specified max-round. * * #### Example * ```typescript @@ -192,7 +192,7 @@ export default class LookupAccountTransactions extends JSONRequest { } /** - * Asset ID to filter with + * Asset ID to filter with. * * #### Example * ```typescript @@ -213,15 +213,15 @@ export default class LookupAccountTransactions extends JSONRequest { } /** - * Maximum number of results to return + * Maximum number of results to return. * * #### Example * ```typescript - * const limit = 25; + * const maxResults = 25; * const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; * const accountTxns = await indexerClient * .lookupAccountTransactions(address) - * .limit(limit) + * .limit(maxResults) * .do(); * ``` * @@ -234,7 +234,7 @@ export default class LookupAccountTransactions extends JSONRequest { } /** - * Include results before the given time + * Include results before the given time. * * #### Example * ```typescript @@ -255,7 +255,7 @@ export default class LookupAccountTransactions extends JSONRequest { } /** - * Include results after the given time + * Include results after the given time. * * #### Example * ```typescript @@ -311,7 +311,7 @@ export default class LookupAccountTransactions extends JSONRequest { } /** - * Filtered results should have an amount less than this value, as int, representing microAlgos, unless an asset-id is provided, in which case units are in the asset's units + * Filtered results should have an amount less than this value, as int, representing microAlgos, unless an asset-id is provided, in which case units are in the asset's units. * * #### Example 1 * ```typescript @@ -348,17 +348,22 @@ export default class LookupAccountTransactions extends JSONRequest { * * #### Example * ```typescript - * const limit = 25; - * const nextToken = "the next token returned in the previous query response"; + * const maxResults = 25; * const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; - * const accountTxns = await indexerClient + * + * const accountTxnsPage1 = await indexerClient + * .lookupAccountTransactions(address) + * .limit(maxResults) + * .do(); + * + * const accountTxnsPage2 = await indexerClient * .lookupAccountTransactions(address) - * .limit(limit) - * .nextToken(nextToken) + * .limit(maxResults) + * .nextToken(accountTxnsPage1["next-token"]) * .do(); * ``` * - * @param nextToken + * @param nextToken - provided by the previous results. * @category query */ nextToken(nextToken: string) { @@ -367,7 +372,7 @@ export default class LookupAccountTransactions extends JSONRequest { } /** - * Include results which include the rekey-to field + * Whether or not to include rekeying transactions. * * #### Example * ```typescript diff --git a/src/client/v2/indexer/lookupApplicationLogs.ts b/src/client/v2/indexer/lookupApplicationLogs.ts index 3d11f8c26..2b945ba7a 100644 --- a/src/client/v2/indexer/lookupApplicationLogs.ts +++ b/src/client/v2/indexer/lookupApplicationLogs.ts @@ -3,46 +3,152 @@ import HTTPClient from '../../client'; import IntDecoding from '../../../types/intDecoding'; export default class LookupApplicationLogs extends JSONRequest { + /** + * Returns log messages generated by the passed in application. + * + * #### Example + * ```typescript + * const appId = 60553466; + * const appLogs = await indexerClient.lookupApplicationLogs(appId).do(); + * ``` + * + * [Response data schema details](https://developer.algorand.org/docs/rest-apis/indexer/#get-v2applicationsapplication-idlogs) + * @param appID - The ID of the application which generated the logs. + * @category GET + */ constructor(c: HTTPClient, intDecoding: IntDecoding, private appID: number) { super(c, intDecoding); this.appID = appID; } + /** + * @returns `/v2/applications/${appID}/logs` + */ path() { return `/v2/applications/${this.appID}/logs`; } - /** limit for filter, as int */ + /** + * Limit results for pagination. + * + * #### Example + * ```typescript + * const maxResults = 20; + * const appLogs = await indexerClient + * .lookupApplicationLogs(appId) + * .limit(maxResults) + * .do(); + * ``` + * + * @param limit - maximum number of results to return. + */ limit(limit: number) { this.query.limit = limit; return this; } - /** min round to filter with, as int */ + /** + * Include results at or after the specified min-round. + * + * #### Example + * ```typescript + * const minRound = 18309917; + * const appLogs = await indexerClient + * .lookupApplicationLogs(appId) + * .minRound(minRound) + * .do(); + * ``` + * + * @param round + * @category query + */ minRound(round: number) { this.query['min-round'] = round; return this; } - /** max round to filter with, as int */ + /** + * Include results at or before the specified max-round. + * + * #### Example + * ```typescript + * const maxRound = 18309917; + * const appLogs = await indexerClient + * .lookupApplicationLogs(appId) + * .maxRound(maxRound) + * .do(); + * ``` + * + * @param round + * @category query + */ maxRound(round: number) { this.query['max-round'] = round; return this; } - /** used for pagination */ + /** + * The next page of results. + * + * #### Example + * ```typescript + * const maxResults = 25; + * + * const appLogsPage1 = await indexerClient + * .lookupApplicationLogs(appId) + * .limit(maxResults) + * .do(); + * + * const appLogsPage2 = await indexerClient + * .lookupApplicationLogs(appId) + * .limit(maxResults) + * .nextToken(appLogsPage1["next-token"]) + * .do(); + * ``` + * + * @param nextToken - provided by the previous results. + * @category query + */ nextToken(nextToken: string) { this.query.next = nextToken; return this; } - /** only include transactions with this sender address */ + /** + * Only include transactions with this sender address. + * + * #### Example + * ```typescript + * const sender = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; + * const appLogs = await indexerClient + * .lookupApplicationLogs(appId) + * .sender(sender) + * .do(); + * ``` + * + * @param senderAddress + * @category query + */ sender(senderAddress: string) { this.query['sender-address'] = senderAddress; return this; } - /** txid to filter with, as string */ + /** + * Lookup the specific transaction by ID. + * + * #### Example + * ```typescript + * const txId = "MEUOC4RQJB23CQZRFRKYEI6WBO73VTTPST5A7B3S5OKBUY6LFUDA"; + * const appLogs = await indexerClient + * .lookupApplicationLogs(appId) + * .txid(txId) + * .do(); + * ``` + * + * @param txid + * @category query + */ txid(txid: string) { this.query.txid = txid; return this; diff --git a/src/client/v2/indexer/lookupApplications.ts b/src/client/v2/indexer/lookupApplications.ts index b0267083e..8fb44291f 100644 --- a/src/client/v2/indexer/lookupApplications.ts +++ b/src/client/v2/indexer/lookupApplications.ts @@ -3,16 +3,55 @@ import HTTPClient from '../../client'; import IntDecoding from '../../../types/intDecoding'; export default class LookupApplications extends JSONRequest { + /** + * Returns information about the passed application. + * + * #### Example + * ```typescript + * const appId = 60553466; + * const appInfo = await indexerClient.lookupApplications(appId).do(); + * ``` + * + * [Response data schema details](https://developer.algorand.org/docs/rest-apis/indexer/#get-v2applicationsapplication-id) + * @param index - The ID of the application to look up. + * @category GET + */ constructor(c: HTTPClient, intDecoding: IntDecoding, private index: number) { super(c, intDecoding); this.index = index; } + /** + * @returns `/v2/applications/${index}` + */ path() { return `/v2/applications/${this.index}`; } - // include all items including closed accounts, deleted applications, destroyed assets, opted-out asset holdings, and closed-out application localstates + /** + * Includes all items including closed accounts, deleted applications, destroyed assets, opted-out asset holdings, and closed-out application localstates + * + * #### Example 1 + * ```typescript + * const appId = 60553466; + * const appInfo = await indexerClient + * .lookupApplications(appId) + * .includeAll(false) + * .do(); + * ``` + * + * #### Example 2 + * ```typescript + * const appId = 60553466; + * const appInfo = await indexerClient + * .lookupApplications(appId) + * .includeAll() + * .do(); + * ``` + * + * @param value - default true when called without passing a value + * @category query + */ includeAll(value = true) { this.query['include-all'] = value; return this; diff --git a/src/client/v2/indexer/lookupAssetBalances.ts b/src/client/v2/indexer/lookupAssetBalances.ts index 04ab81345..d11795bcb 100644 --- a/src/client/v2/indexer/lookupAssetBalances.ts +++ b/src/client/v2/indexer/lookupAssetBalances.ts @@ -20,12 +20,15 @@ export default class LookupAssetBalances extends JSONRequest { this.index = index; } + /** + * @returns `/v2/assets/${index}/balances` + */ path() { return `/v2/assets/${this.index}/balances`; } /** - * Add a limit for filter. + * Limit results for pagination. * * #### Example * ```typescript @@ -38,6 +41,7 @@ export default class LookupAssetBalances extends JSONRequest { * ``` * * @param limit - maximum number of results to return. + * @category query */ limit(limit: number) { this.query.limit = limit; @@ -57,6 +61,7 @@ export default class LookupAssetBalances extends JSONRequest { * .do(); * ``` * @param greater + * @category query */ currencyGreaterThan(greater: number) { this.query['currency-greater-than'] = greater; @@ -76,6 +81,7 @@ export default class LookupAssetBalances extends JSONRequest { * .do(); * ``` * @param lesser + * @category query */ currencyLessThan(lesser: number) { this.query['currency-less-than'] = lesser; @@ -89,14 +95,20 @@ export default class LookupAssetBalances extends JSONRequest { * ```typescript * const assetId = 163650; * const maxResults = 20; - * const nextToken = "APA6C7C3NCANRPIBUWQOF7WSKLJMK6RPQUVFLLDV4U5WCQE4DEF26D4E3E"; - * const assetBalances = await indexerClient + * + * const assetBalancesPage1 = await indexerClient * .lookupAssetBalances(assetId) * .limit(maxResults) - * .next(nextToken) + * .do(); + * + * const assetBalancesPage2 = await indexerClient + * .lookupAssetBalances(assetId) + * .limit(maxResults) + * .nextToken(assetBalancesPage1["next-token"]) * .do(); * ``` * @param nextToken - provided by the previous results. + * @category query */ nextToken(nextToken: string) { this.query.next = nextToken; @@ -104,9 +116,9 @@ export default class LookupAssetBalances extends JSONRequest { } /** - * Include all items including closed accounts, deleted applications, destroyed assets, opted-out asset holdings, and closed-out application localstates + * Include all items including closed accounts, deleted applications, destroyed assets, opted-out asset holdings, and closed-out application localstates. * - * #### Example + * #### Example 1 * ```typescript * const assetId = 163650; * const assetBalances = await indexerClient @@ -114,7 +126,18 @@ export default class LookupAssetBalances extends JSONRequest { * .includeAll(false) * .do(); * ``` + * + * #### Example 2 + * ```typescript + * const assetId = 163650; + * const assetBalances = await indexerClient + * .lookupAssetBalances(assetId) + * .includeAll() + * .do(); + * ``` + * * @param value + * @category query */ includeAll(value = true) { this.query['include-all'] = value; diff --git a/src/client/v2/indexer/lookupAssetByID.ts b/src/client/v2/indexer/lookupAssetByID.ts index 01f9fe866..76331fb2c 100644 --- a/src/client/v2/indexer/lookupAssetByID.ts +++ b/src/client/v2/indexer/lookupAssetByID.ts @@ -32,6 +32,7 @@ export default class LookupAssetByID extends JSONRequest { * * #### Example 1 * ```typescript + * const assetId = 163650; * const assetInfo = await indexerClient * .lookupAssetByID(assetId) * .includeAll(false) @@ -40,6 +41,7 @@ export default class LookupAssetByID extends JSONRequest { * * #### Example 2 * ```typescript + * const assetId = 163650; * const assetInfo = await indexerClient * .lookupAssetByID(assetId) * .includeAll() diff --git a/src/client/v2/indexer/lookupAssetTransactions.ts b/src/client/v2/indexer/lookupAssetTransactions.ts index 92ca064c1..45f1589aa 100644 --- a/src/client/v2/indexer/lookupAssetTransactions.ts +++ b/src/client/v2/indexer/lookupAssetTransactions.ts @@ -4,121 +4,401 @@ import IntDecoding from '../../../types/intDecoding'; import { base64StringFunnel } from './lookupAccountTransactions'; export default class LookupAssetTransactions extends JSONRequest { + /** + * Returns transactions relating to the given asset. + * + * #### Example + * ```typescript + * const assetId = 163650; + * const assetTxns = await indexerClient.lookupAssetTransactions(assetId).do(); + * ``` + * + * [Response data schema details](https://developer.algorand.org/docs/rest-apis/indexer/#get-v2assetsasset-idtransactions) + * @param index - The asset ID to look up. + */ constructor(c: HTTPClient, intDecoding: IntDecoding, private index: number) { super(c, intDecoding); this.index = index; } + /** + * @returns `/v2/assets/${index}/transactions` + */ path() { return `/v2/assets/${this.index}/transactions`; } /** - * notePrefix to filter with + * Specifies a prefix which must be contained in the note field. + * + * #### Example + * ```typescript + * const notePrefixBase64Encoded = "Y3JlYXRl"; + * const assetId = 163650; + * const assetTxns = await indexerClient + * .lookupAssetTransactions(assetId) + * .notePrefix(notePrefixBase64Encoded) + * .do(); + * ``` + * * @param prefix - base64 string or uint8array + * @category query */ notePrefix(prefix: Uint8Array | string) { this.query['note-prefix'] = base64StringFunnel(prefix); return this; } - // txtype to filter with, as string + /** + * Type of transaction to filter with. + * + * #### Example + * ```typescript + * const assetId = 163650; + * const assetTxns = await indexerClient + * .lookupAssetTransactions(assetId) + * .txType("axfer") + * .do(); + * ``` + * + * @param type - one of `pay`, `keyreg`, `acfg`, `axfer`, `afrz`, `appl` + * @category query + */ txType(type: string) { this.query['tx-type'] = type; return this; } - // sigtype to filter with, as string + /** + * Type of signature to filter with. + * - sig: Standard + * - msig: MultiSig + * - lsig: LogicSig + * + * #### Example + * ```typescript + * const assetId = 163650; + * const assetTxns = await indexerClient + * .lookupAssetTransactions(assetId) + * .sigType("lsig") + * .do(); + * ``` + * + * @param type - one of `sig`, `msig`, `lsig` + * @category query + */ sigType(type: string) { this.query['sig-type'] = type; return this; } - // txid to filter with, as string + /** + * Lookup the specific transaction by ID. + * + * #### Example + * ```typescript + * const txId = "MEUOC4RQJB23CQZRFRKYEI6WBO73VTTPST5A7B3S5OKBUY6LFUDA"; + * const assetId = 163650; + * const assetTxns = await indexerClient + * .lookupAssetTransactions(assetId) + * .txid(txId) + * .do(); + * ``` + * + * @param txid + * @category query + */ txid(txid: string) { this.query.txid = txid; return this; } - // round to filter with, as int + /** + * Include results for the specified round. + * + * #### Example + * ```typescript + * const targetBlock = 18309917; + * const assetId = 163650; + * const assetTxns = await indexerClient + * .lookupAssetTransactions(assetId) + * .round(targetBlock) + * .do(); + * ``` + * + * @param round + * @category query + */ round(round: number) { this.query.round = round; return this; } - // min round to filter with, as int + /** + * Include results at or after the specified min-round. + * + * #### Example + * ```typescript + * const minRound = 18309917; + * const assetId = 163650; + * const assetTxns = await indexerClient + * .lookupAssetTransactions(assetId) + * .minRound(minRound) + * .do(); + * ``` + * + * @param round + * @category query + */ minRound(round: number) { this.query['min-round'] = round; return this; } - // max round to filter with, as int + /** + * Include results at or before the specified max-round. + * + * #### Example + * ```typescript + * const maxRound = 18309917; + * const assetId = 163650; + * const assetTxns = await indexerClient + * .lookupAssetTransactions(assetId) + * .maxRound(maxRound) + * .do(); + * ``` + * + * @param round + * @category query + */ maxRound(round: number) { this.query['max-round'] = round; return this; } - // asset ID to filter with, as int + /** + * @deprecated Redundant query parameter. Asset ID is already passed into the method. + */ assetID(id: number) { this.query['asset-id'] = id; return this; } - // limit for filter, as int + /** + * Maximum number of results to return. + * + * #### Example + * ```typescript + * const maxResults = 25; + * const assetId = 163650; + * const assetTxns = await indexerClient + * .lookupAssetTransactions(assetId) + * .limit(maxResults) + * .do(); + * ``` + * + * @param limit + * @category query + */ limit(limit: number) { this.query.limit = limit; return this; } - // before-time to filter with, as rfc3339 string + /** + * Include results before the given time. + * + * #### Example + * ```typescript + * const beforeTime = "2022-02-02T20:20:22.02Z"; + * const assetId = 163650; + * const assetTxns = await indexerClient + * .lookupAssetTransactions(assetId) + * .beforeTime(beforeTime) + * .do(); + * ``` + * + * @param before - rfc3339 string + * @category query + */ beforeTime(before: string) { this.query['before-time'] = before; return this; } - // after-time to filter with, as rfc3339 string + /** + * Include results after the given time. + * + * #### Example + * ```typescript + * const afterTime = "2022-10-21T00:00:11.55Z"; + * const assetId = 163650; + * const assetTxns = await indexerClient + * .lookupAssetTransactions(assetId) + * .afterTime(afterTime) + * .do(); + * ``` + * + * @param after - rfc3339 string + * @category query + */ afterTime(after: string) { this.query['after-time'] = after; return this; } - // filtered results should have an amount greater than this value, as int, representing asset units + /** + * Filtered results should have an amount greater than this value, as int, representing asset units. + * + * #### Example + * ```typescript + * const minBalance = 300000; + * const assetId = 163650; + * const assetTxns = await indexerClient + * .lookupAssetTransactions(assetId) + * .currencyGreaterThan(minBalance - 1) + * .do(); + * ``` + * + * @remarks + * If you are looking for transactions 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. + * + * @param greater + * @category query + */ currencyGreaterThan(greater: number) { this.query['currency-greater-than'] = greater; return this; } - // filtered results should have an amount less than this value, as int, representing asset units + /** + * Filtered results should have an amount less than this value, as int, representing asset units. + * + * #### Example + * ```typescript + * const maxBalance = 500000; + * const assetId = 163650; + * const assetTxns = await indexerClient + * .lookupAssetTransactions(assetId) + * .currencyLessThan(maxBalance + 1) + * .do(); + * ``` + * + * @param lesser + * @category query + */ currencyLessThan(lesser: number) { this.query['currency-less-than'] = lesser; return this; } - // combined with address, defines what address to filter on, as string + /** + * Combined with address, defines what address to filter on, as string. + * + * #### Example + * ```typescript + * const assetId = 163650; + * const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; + * const role = "sender"; + * const assetTxns = await indexerClient + * .lookupAssetTransactions(assetId) + * .address(address) + * .addressRole(role) + * .do(); + * ``` + * + * @param role - one of `sender`, `receiver`, `freeze-target` + * @category query + */ addressRole(role: string) { this.query['address-role'] = role; return this; } - // address to filter on as string + /** + * Only include transactions with this address in one of the transaction fields. + * + * #### Example + * ```typescript + * const assetId = 163650; + * const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; + * const assetTxns = await indexerClient + * .lookupAssetTransactions(assetId) + * .address(address) + * .do(); + * ``` + * + * @param address + * @category query + */ address(address: string) { this.query.address = address; return this; } - // whether or not to consider the close-to field as a receiver when filtering transactions, as bool. set to true to ignore close-to + /** + * Whether or not to consider the `close-to` field as a receiver when filtering transactions, as bool. Set to `true` to ignore `close-to`. + * + * #### Example + * ```typescript + * const assetId = 163650; + * const assetTxns = await indexerClient + * .lookupAssetTransactions(assetId) + * .excludeCloseTo(true) + * .do(); + * ``` + * + * @param exclude + * @category query + */ excludeCloseTo(exclude: boolean) { this.query['exclude-close-to'] = exclude; return this; } - // used for pagination + /** + * The next page of results. + * + * #### Example + * ```typescript + * const maxResults = 25; + * const assetId = 163650; + * + * const assetTxnsPage1 = await indexerClient + * .lookupAssetTransactions(assetId) + * .limit(maxResults) + * .do(); + * + * const assetTxnsPage2 = await indexerClient + * .lookupAssetTransactions(assetId) + * .limit(maxResults) + * .nextToken(assetTxnsPage1["next-token"]) + * .do(); + * ``` + * + * @param nextToken - provided by the previous results. + * @category query + */ nextToken(nextToken: string) { this.query.next = nextToken; return this; } - // whether or not to include rekeying transactions + /** + * Whether or not to include rekeying transactions. + * + * #### Example + * ```typescript + * const assetId = 163650; + * const assetTxns = await indexerClient + * .lookupAssetTransactions(assetId) + * .rekeyTo(false) + * .do(); + * ``` + * + * @param rekeyTo + * @category query + */ rekeyTo(rekeyTo: boolean) { this.query['rekey-to'] = rekeyTo; return this; diff --git a/src/client/v2/indexer/lookupBlock.ts b/src/client/v2/indexer/lookupBlock.ts index 9261b52ca..d722827cf 100644 --- a/src/client/v2/indexer/lookupBlock.ts +++ b/src/client/v2/indexer/lookupBlock.ts @@ -3,11 +3,27 @@ import HTTPClient from '../../client'; import IntDecoding from '../../../types/intDecoding'; export default class LookupBlock extends JSONRequest { + /** + * Returns the block for the passed round. + * + * #### Example + * ```typescript + * const targetBlock = 18309917; + * const blockInfo = await indexerClient.lookupBlock(targetBlock).do(); + * ``` + * + * [Response data schema details](https://developer.algorand.org/docs/rest-apis/indexer/#get-v2blocksround-number) + * @param round - The number of the round to look up. + * @category GET + */ constructor(c: HTTPClient, intDecoding: IntDecoding, private round: number) { super(c, intDecoding); this.round = round; } + /** + * @returns `/v2/blocks/${round}` + */ path() { return `/v2/blocks/${this.round}`; } diff --git a/src/client/v2/indexer/lookupTransactionByID.ts b/src/client/v2/indexer/lookupTransactionByID.ts index 4cd98700a..d834db3ff 100644 --- a/src/client/v2/indexer/lookupTransactionByID.ts +++ b/src/client/v2/indexer/lookupTransactionByID.ts @@ -3,11 +3,27 @@ import HTTPClient from '../../client'; import IntDecoding from '../../../types/intDecoding'; export default class LookupTransactionByID extends JSONRequest { + /** + * Returns information about the given transaction. + * + * #### Example + * ```typescript + * const txnId = "MEUOC4RQJB23CQZRFRKYEI6WBO73VTTPST5A7B3S5OKBUY6LFUDA"; + * const txnInfo = await indexerClient.lookupTransactionByID(txnId).do(); + * ``` + * + * [Response data schema details](https://developer.algorand.org/docs/rest-apis/indexer/#get-v2transactionstxid) + * @param txID - The ID of the transaction to look up. + * @category GET + */ constructor(c: HTTPClient, intDecoding: IntDecoding, private txID: string) { super(c, intDecoding); this.txID = txID; } + /** + * @returns `/v2/transactions/${txID}` + */ path() { return `/v2/transactions/${this.txID}`; } diff --git a/src/client/v2/indexer/makeHealthCheck.ts b/src/client/v2/indexer/makeHealthCheck.ts index 0b5137ccb..61059b045 100644 --- a/src/client/v2/indexer/makeHealthCheck.ts +++ b/src/client/v2/indexer/makeHealthCheck.ts @@ -1,6 +1,21 @@ import JSONRequest from '../jsonrequest'; +/** + * Returns the health object for the service. + * Returns 200 if healthy. + * + * #### Example + * ```typescript + * const health = await indexerClient.makeHealthCheck().do(); + * ``` + * + * [Response data schema details](https://developer.algorand.org/docs/rest-apis/indexer/#get-health) + * @category GET + */ export default class MakeHealthCheck extends JSONRequest { + /** + * @returns `/health` + */ // eslint-disable-next-line class-methods-use-this path() { return '/health'; diff --git a/src/client/v2/indexer/searchAccounts.ts b/src/client/v2/indexer/searchAccounts.ts index 34a99c99b..31a62f02d 100644 --- a/src/client/v2/indexer/searchAccounts.ts +++ b/src/client/v2/indexer/searchAccounts.ts @@ -1,66 +1,266 @@ import JSONRequest from '../jsonrequest'; +/** + * Returns information about indexed accounts. + * + * #### Example + * ```typescript + * const accounts = await indexerClient.searchAccounts().do(); + * ``` + * + * [Response data schema details](https://developer.algorand.org/docs/rest-apis/indexer/#get-v2accounts) + * @category GET + */ export default class SearchAccounts extends JSONRequest { + /** + * @returns `/v2/accounts` + */ // eslint-disable-next-line class-methods-use-this path() { return '/v2/accounts'; } - // filtered results should have an amount greater than this value, as int, representing microAlgos, unless an asset-id is provided, in which case units are in the asset's units + /** + * Filtered results should have an amount greater than this value, as int, representing microAlgos, unless an asset-id is provided, in which case units are in the asset's units. + * + * #### Example 1 + * ```typescript + * const minBalance = 300000; + * const accounts = await indexerClient + * .searchAccounts() + * .currencyGreaterThan(minBalance - 1) + * .do(); + * ``` + * + * #### Example 2 + * ```typescript + * const assetID = 163650; + * const minBalance = 300000; + * const accounts = await indexerClient + * .searchAccounts() + * .assetID(assetID) + * .currencyGreaterThan(minBalance - 1) + * .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. + * + * @param greater + * @category query + */ currencyGreaterThan(greater: number) { this.query['currency-greater-than'] = greater; return this; } - // filtered results should have an amount less than this value, as int, representing microAlgos, unless an asset-id is provided, in which case units are in the asset's units + /** + * Filtered results should have an amount less than this value, as int, representing microAlgos, unless an asset-id is provided, in which case units are in the asset's units. + * + * #### Example 1 + * ```typescript + * const maxBalance = 500000; + * const accounts = await indexerClient + * .searchAccounts() + * .currencyLessThan(maxBalance + 1) + * .do(); + * ``` + * + * #### Example 2 + * ```typescript + * const assetID = 163650; + * const maxBalance = 500000; + * const accounts = await indexerClient + * .searchAccounts() + * .assetID(assetID) + * .currencyLessThan(maxBalance + 1) + * .do(); + * ``` + * + * @param lesser + * @category query + */ currencyLessThan(lesser: number) { this.query['currency-less-than'] = lesser; return this; } - // limit for filter, as int + /** + * Maximum number of results to return. + * + * #### Example + * ```typescript + * const maxResults = 25; + * const accounts = await indexerClient + * .searchAccounts() + * .limit(maxResults) + * .do(); + * ``` + * + * @param limit + * @category query + */ limit(limit: number) { this.query.limit = limit; return this; } - // asset ID to filter with, as int + /** + * Asset ID to filter with. + * + * #### Example + * ```typescript + * const assetID = 163650; + * const accounts = await indexerClient + * .searchAccounts() + * .assetID(assetID) + * .do(); + * ``` + * + * @param id + * @category query + */ assetID(id: number) { this.query['asset-id'] = id; return this; } - // used for pagination + /** + * The next page of results. + * + * #### Example + * ```typescript + * const maxResults = 25; + * + * const accountsPage1 = await indexerClient + * .searchAccounts() + * .limit(maxResults) + * .do(); + * + * const accountsPage2 = await indexerClient + * .searchAccounts() + * .limit(maxResults) + * .nextToken(accountsPage1["next-token"]) + * .do(); + * ``` + * + * @param nextToken - provided by the previous results + * @category query + */ nextToken(nextToken: string) { this.query.next = nextToken; return this; } - // specific round to search + /** + * Include results for the specified round. + * + * #### Example + * ```typescript + * const targetBlock = 18309917; + * const accounts = await indexerClient + * .searchAccounts() + * .round(targetBlock) + * .do(); + * ``` + * @remarks For performance reasons, this parameter may be disabled on some configurations. + * @param round + * @category query + */ round(round: number) { this.query.round = round; return this; } - // include accounts that use this spending key + /** + * Include accounts that use this spending key. + * + * #### Example + * ```typescript + * const authAddr = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; + * const accounts = await indexerClient + * .searchAccounts() + * .authAddr(authAddr) + * .do(); + * ``` + * + * @param authAddr + */ authAddr(authAddr: string) { this.query['auth-addr'] = authAddr; return this; } - // filter for this application + /** + * Filter for this application. + * + * #### Example + * ```typescript + * const appId = 60553466; + * const accounts = await indexerClient + * .searchAccounts() + * .applicationID(appId) + * .do(); + * ``` + * + * @param applicationID + * @category query + */ applicationID(applicationID: number) { this.query['application-id'] = applicationID; return this; } - // include all items including closed accounts, deleted applications, destroyed assets, opted-out asset holdings, and closed-out application localstates + /** + * Includes all items including closed accounts, deleted applications, destroyed assets, opted-out asset holdings, and closed-out application localstates + * + * #### Example 1 + * ```typescript + * const assetId = 163650; + * const accounts = await indexerClient + * .searchAccounts() + * .includeAll(false) + * .do(); + * ``` + * + * #### Example 2 + * ```typescript + * const assetId = 163650; + * const accounts = await indexerClient + * .searchAccounts() + * .includeAll() + * .do(); + * ``` + * + * @param value - default true when called without passing a value + * @category query + */ includeAll(value = true) { this.query['include-all'] = value; return this; } - // exclude + /** + * Exclude additional items such as asset holdings, application local data stored for this account, asset parameters created by this account, and application parameters created by this account. + * + * #### Example 1 + * ```typescript + * const accounts = await indexerClient + * .searchAccounts() + * .exclude("all") + * .do(); + * ``` + * + * #### Example 2 + * ```typescript + * const accounts = await indexerClient + * .searchAccounts() + * .exclude("assets,created-assets") + * .do(); + * ``` + * @remarks By default, it behaves as exclude=none + * @param exclude - Array of `all`, `assets`, `created-assets`, `apps-local-state`, `created-apps`, `none` + * @category query + */ exclude(exclude: string) { this.query.exclude = exclude; return this; diff --git a/src/client/v2/indexer/searchForApplications.ts b/src/client/v2/indexer/searchForApplications.ts index ec6f272ea..abf122fef 100644 --- a/src/client/v2/indexer/searchForApplications.ts +++ b/src/client/v2/indexer/searchForApplications.ts @@ -1,36 +1,132 @@ import JSONRequest from '../jsonrequest'; +/** + * Returns information about indexed applications. + * + * #### Example + * ```typescript + * const apps = await indexerClient.searchForApplications().do(); + * ``` + * + * [Response data schema details](https://developer.algorand.org/docs/rest-apis/indexer/#get-v2applications) + * @category GET + */ export default class SearchForApplications extends JSONRequest { + /** + * @returns `/v2/applications` + */ // eslint-disable-next-line class-methods-use-this path() { return '/v2/applications'; } - // application ID for filter, as int + /** + * Application ID for filter, as int + * + * #### Example + * ```typescript + * const appId = 60553466; + * const apps = await indexerClient + * .searchForApplications() + * .index(appId) + * .do(); + * ``` + * @remarks Alternatively, use `indexerClient.lookupApplications(appId).do()` + * @param index + * @category query + */ index(index: number) { this.query['application-id'] = index; return this; } - // creator for filter, as string + /** + * Creator for filter, as string + * + * #### Example + * ```typescript + * const creator = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; + * const apps = await indexerClient + * .searchForApplications() + * .creator(creator) + * .do(); + * ``` + * @param creator + * @category query + */ creator(creator: string) { this.query.creator = creator; return this; } - // token for pagination + /** + * Specify the next page of results. + * + * #### Example + * ```typescript + * const maxResults = 20; + * + * const appsPage1 = await indexerClient + * .searchForApplications() + * .limit(maxResults) + * .do(); + * + * const appsPage2 = await indexerClient + * .searchForApplications() + * .limit(maxResults) + * .nextToken(appsPage1["next-token"]) + * .do(); + * ``` + * @param nextToken - provided by the previous results. + * @category query + */ nextToken(next: string) { this.query.next = next; return this; } - // limit results for pagination + /** + * Limit results for pagination. + * + * #### Example + * ```typescript + * const maxResults = 20; + * const apps = await indexerClient + * .searchForApplications() + * .limit(maxResults) + * .do(); + * ``` + * + * @param limit - maximum number of results to return. + * @category query + */ limit(limit: number) { this.query.limit = limit; return this; } - // include all items including closed accounts, deleted applications, destroyed assets, opted-out asset holdings, and closed-out application localstates + /** + * Includes all items including closed accounts, deleted applications, destroyed assets, opted-out asset holdings, and closed-out application localstates + * + * #### Example 1 + * ```typescript + * const apps = await indexerClient + * .searchForApplications() + * .includeAll(false) + * .do(); + * ``` + * + * #### Example 2 + * ```typescript + * const apps = await indexerClient + * .searchForApplications() + * .includeAll() + * .do(); + * ``` + * + * @param value - default true when called without passing a value + * @category query + */ includeAll(value = true) { this.query['include-all'] = value; return this; diff --git a/src/client/v2/indexer/searchForAssets.ts b/src/client/v2/indexer/searchForAssets.ts index 9f49bbda9..79fa8c66d 100644 --- a/src/client/v2/indexer/searchForAssets.ts +++ b/src/client/v2/indexer/searchForAssets.ts @@ -1,48 +1,173 @@ import JSONRequest from '../jsonrequest'; +/** + * Returns information about indexed assets. + * + * #### Example + * ```typescript + * const assets = await indexerClient.searchForAssets().do(); + * ``` + * + * [Response data schema details](https://developer.algorand.org/docs/rest-apis/indexer/#get-v2assets) + * @category GET + */ export default class SearchForAssets extends JSONRequest { + /** + * @returns `/v2/assets` + */ // eslint-disable-next-line class-methods-use-this path() { return '/v2/assets'; } - // limit for filter, as int + /** + * Limit results for pagination. + * + * #### Example + * ```typescript + * const maxResults = 20; + * const assets = await indexerClient + * .searchForAssets() + * .limit(maxResults) + * .do(); + * ``` + * + * @param limit - maximum number of results to return. + * @category query + */ limit(limit: number) { this.query.limit = limit; return this; } - // asset creator address for filter, as string + /** + * Filter just assets with the given creator address. + * + * #### Example + * ```typescript + * const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; + * const assets = await indexerClient + * .searchForAssets() + * .creator(address) + * .do(); + * ``` + * + * @param creator + * @category query + */ creator(creator: string) { this.query.creator = creator; return this; } - // asset name for filter, as string + /** + * Filter just assets with the given name. + * + * #### Example + * ```typescript + * const name = "Test Token"; + * const assets = await indexerClient + * .searchForAssets() + * .name(name) + * .do(); + * ``` + * + * @param name + * @category query + */ name(name: string) { this.query.name = name; return this; } - // asset unit name for filter, as string + /** + * Filter just assets with the given unit. + * + * #### Example + * ```typescript + * const unit = "test"; + * const assets = await indexerClient + * .searchForAssets() + * .unit(unit) + * .do(); + * ``` + * + * @param unit + * @category query + */ unit(unit: string) { this.query.unit = unit; return this; } - // asset ID for filter, as int + /** + * Asset ID for filter, as int. + * + * #### Example + * ```typescript + * const assetId = 163650; + * const assets = await indexerClient + * .searchForAssets() + * .index(assetId) + * .do(); + * ``` + * @remarks Alternatively, use `indexerClient.lookupAssetByID(assetId).do();` + * @param index + * @category query + */ index(index: number) { this.query['asset-id'] = index; return this; } - // used for pagination + /** + * Specify the next page of results. + * + * #### Example + * ```typescript + * const maxResults = 20; + * + * const assetsPage1 = await indexerClient + * .searchForAssets() + * .limit(maxResults) + * .do(); + * + * const assetsPage2 = await indexerClient + * .searchForAssets() + * .limit(maxResults) + * .nextToken(assetsPage1["next-token"]) + * .do(); + * ``` + * @param nextToken - provided by the previous results. + * @category query + */ nextToken(nextToken: string) { this.query.next = nextToken; return this; } - // include all items including closed accounts, deleted applications, destroyed assets, opted-out asset holdings, and closed-out application localstates + /** + * Includes all items including closed accounts, deleted applications, destroyed assets, opted-out asset holdings, and closed-out application localstates + * + * #### Example 1 + * ```typescript + * const assets = await indexerClient + * .searchForAssets() + * .includeAll(false) + * .do(); + * ``` + * + * #### Example 2 + * ```typescript + * const assets = await indexerClient + * .searchForAssets() + * .includeAll() + * .do(); + * ``` + * + * @param value - default true when called without passing a value + * @category query + */ includeAll(value = true) { this.query['include-all'] = value; return this; diff --git a/src/client/v2/indexer/searchForTransactions.ts b/src/client/v2/indexer/searchForTransactions.ts index 8ee5e55aa..5afa84c29 100644 --- a/src/client/v2/indexer/searchForTransactions.ts +++ b/src/client/v2/indexer/searchForTransactions.ts @@ -1,124 +1,433 @@ import JSONRequest from '../jsonrequest'; import { base64StringFunnel } from './lookupAccountTransactions'; +/** + * Returns information about indexed transactions. + * + * #### Example + * ```typescript + * const txns = await indexerClient.searchForTransactions().do(); + * ``` + * + * [Response data schema details](https://developer.algorand.org/docs/rest-apis/indexer/#get-v2transactions) + * @category GET + */ export default class SearchForTransactions extends JSONRequest { + /** + * @returns `/v2/transactions` + */ // eslint-disable-next-line class-methods-use-this path() { return '/v2/transactions'; } /** - * notePrefix to filter with + * Specifies a prefix which must be contained in the note field. + * + * #### Example + * ```typescript + * const notePrefixBase64Encoded = "Y3JlYXRl"; + * const txns = await indexerClient + * .searchForTransactions() + * .notePrefix(notePrefixBase64Encoded) + * .do(); + * ``` + * * @param prefix - base64 string or uint8array + * @category query */ notePrefix(prefix: Uint8Array | string) { this.query['note-prefix'] = base64StringFunnel(prefix); return this; } - // txtype to filter with, as string + /** + * Type of transaction to filter with. + * + * #### Example + * ```typescript + * const txns = await indexerClient + * .searchForTransactions() + * .txType("keyreg") + * .do(); + * ``` + * + * @param type - one of `pay`, `keyreg`, `acfg`, `axfer`, `afrz`, `appl` + * @category query + */ txType(type: string) { this.query['tx-type'] = type; return this; } - // sigtype to filter with, as string + /** + * Type of signature to filter with. + * - sig: Standard + * - msig: MultiSig + * - lsig: LogicSig + * + * #### Example + * ```typescript + * const txns = await indexerClient + * .searchForTransactions() + * .sigType("sig") + * .do(); + * ``` + * + * @param type - one of `sig`, `msig`, `lsig` + * @category query + */ sigType(type: string) { this.query['sig-type'] = type; return this; } - // txid to filter with, as string + /** + * Lookup the specific transaction by ID. + * + * #### Example + * ```typescript + * const txId = "MEUOC4RQJB23CQZRFRKYEI6WBO73VTTPST5A7B3S5OKBUY6LFUDA"; + * const txns = await indexerClient + * .searchForTransactions() + * .txid(txId) + * .do(); + * ``` + * @remarks Alternatively, use `indexerClient.lookupTransactionByID(txnId).do()` + * @param txid + * @category query + */ txid(txid: string) { this.query.txid = txid; return this; } - // round to filter with, as int + /** + * Include results for the specified round. + * + * #### Example + * ```typescript + * const targetBlock = 18309917; + * const txns = await indexerClient + * .searchForTransactions() + * .round(targetBlock) + * .do(); + * ``` + * @remarks Alternatively, use `indexerClient.lookupBlock(targetBlock).do()` + * @param round + * @category query + */ round(round: number) { this.query.round = round; return this; } - // min round to filter with, as int + /** + * Include results at or after the specified min-round. + * + * #### Example + * ```typescript + * const minRound = 18309917; + * const txns = await indexerClient + * .searchForTransactions() + * .minRound(minRound) + * .do(); + * ``` + * + * @param round + * @category query + */ minRound(round: number) { this.query['min-round'] = round; return this; } - // max round to filter with, as int + /** + * Include results at or before the specified max-round. + * + * #### Example + * ```typescript + * const maxRound = 18309917; + * const txns = await indexerClient + * .searchForTransactions() + * .maxRound(maxRound) + * .do(); + * ``` + * + * @param round + * @category query + */ maxRound(round: number) { this.query['max-round'] = round; return this; } - // asset ID to filter with, as int + /** + * Asset ID to filter with. + * + * #### Example + * ```typescript + * const assetID = 163650; + * const txns = await indexerClient + * .searchForTransactions() + * .assetID(assetID) + * .do(); + * ``` + * @remarks Alternatively, use `indexerClient.lookupAssetTransactions(assetId).do()` + * @param id + * @category query + */ assetID(id: number) { this.query['asset-id'] = id; return this; } - // limit for filter, as int + /** + * Maximum number of results to return. + * + * #### Example + * ```typescript + * const maxResults = 25; + * const txns = await indexerClient + * .searchForTransactions() + * .limit(maxResults) + * .do(); + * ``` + * + * @param limit + * @category query + */ limit(limit: number) { this.query.limit = limit; return this; } - // before-time to filter with, as rfc3339 string + /** + * Include results before the given time. + * + * #### Example + * ```typescript + * const beforeTime = "2022-02-02T20:20:22.02Z"; + * const txns = await indexerClient + * .searchForTransactions() + * .beforeTime(beforeTime) + * .do(); + * ``` + * + * @param before - rfc3339 string + * @category query + */ beforeTime(before: string) { this.query['before-time'] = before; return this; } - // after-time to filter with, as rfc3339 string + /** + * Include results after the given time. + * + * #### Example + * ```typescript + * const afterTime = "2022-10-21T00:00:11.55Z"; + * const txns = await indexerClient + * .searchForTransactions() + * .afterTime(afterTime) + * .do(); + * ``` + * + * @param after - rfc3339 string + * @category query + */ afterTime(after: string) { this.query['after-time'] = after; return this; } - // filtered results should have an amount greater than this value, as int, representing microAlgos, unless an asset-id is provided, in which case units are in the asset's units + /** + * Filtered results should have an amount greater than this value, as int, representing microAlgos, unless an asset-id is provided, in which case units are in the asset's units. + * + * #### Example 1 + * ```typescript + * const minBalance = 300000; + * const txns = await indexerClient + * .searchForTransactions() + * .currencyGreaterThan(minBalance - 1) + * .do(); + * ``` + * + * #### Example 2 + * ```typescript + * const assetID = 163650; + * const minBalance = 300000; + * const txns = await indexerClient + * .searchForTransactions() + * .assetID(assetID) + * .currencyGreaterThan(minBalance - 1) + * .do(); + * ``` + * @remarks + * If you are looking for transactions 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. + * + * @param greater + * @category query + */ currencyGreaterThan(greater: number) { this.query['currency-greater-than'] = greater; return this; } - // filtered results should have an amount less than this value, as int, representing microAlgos, unless an asset-id is provided, in which case units are in the asset's units + /** + * Filtered results should have an amount less than this value, as int, representing microAlgos, unless an asset-id is provided, in which case units are in the asset's units. + * + * #### Example 1 + * ```typescript + * const maxBalance = 500000; + * const txns = await indexerClient + * .searchForTransactions() + * .currencyLessThan(maxBalance + 1) + * .do(); + * ``` + * + * #### Example 2 + * ```typescript + * const assetID = 163650; + * const maxBalance = 500000; + * const txns = await indexerClient + * .searchForTransactions() + * .assetID(assetID) + * .currencyLessThan(maxBalance + 1) + * .do(); + * ``` + * + * @param lesser + * @category query + */ currencyLessThan(lesser: number) { this.query['currency-less-than'] = lesser; return this; } - // combined with address, defines what address to filter on, as string + /** + * Combined with address, defines what address to filter on, as string. + * + * #### Example + * ```typescript + * const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; + * const role = "freeze-target"; + * const txns = await indexerClient + * .searchForTransactions() + * .address(address) + * .addressRole(role) + * .do(); + * ``` + * + * @param role - one of `sender`, `receiver`, `freeze-target` + * @category query + */ addressRole(role: string) { this.query['address-role'] = role; return this; } - // address to filter with, as string + /** + * Only include transactions with this address in one of the transaction fields. + * + * #### Example + * ```typescript + * const address = "XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA"; + * const txns = await indexerClient + * .searchForTransactions() + * .address(address) + * .do(); + * ``` + * @remarks Alternatively, use `indexerClient.lookupAccountTransactions(address).do()` + * @param address + * @category query + */ address(address: string) { this.query.address = address; return this; } - // whether or not to consider the close-to field as a receiver when filtering transactions, as bool. set to true to ignore close-to + /** + * Whether or not to consider the `close-to` field as a receiver when filtering transactions, as bool. Set to `true` to ignore `close-to`. + * + * #### Example + * ```typescript + * const txns = await indexerClient + * .searchForTransactions() + * .excludeCloseTo(true) + * .do(); + * ``` + * + * @param exclude + * @category query + */ excludeCloseTo(exclude: boolean) { this.query['exclude-close-to'] = exclude; return this; } - // used for pagination + /** + * The next page of results. + * + * #### Example + * ```typescript + * const maxResults = 25; + * + * const txnsPage1 = await indexerClient + * .searchForTransactions() + * .limit(maxResults) + * .do(); + * + * const txnsPage2 = await indexerClient + * .searchForTransactions() + * .limit(maxResults) + * .nextToken(txnsPage1["next-token"]) + * .do(); + * ``` + * + * @param nextToken - provided by the previous results + * @category query + */ nextToken(nextToken: string) { this.query.next = nextToken; return this; } - // whether or not to include rekeying transactions + /** + * Whether or not to include rekeying transactions. + * + * #### Example + * ```typescript + * const txns = await indexerClient + * .searchForTransactions() + * .rekeyTo(false) + * .do(); + * ``` + * + * @param rekeyTo + * @category query + */ rekeyTo(rekeyTo: boolean) { this.query['rekey-to'] = rekeyTo; return this; } - // filter for this application + /** + * Filter for this application. + * + * #### Example + * ```typescript + * const appId = 60553466; + * const txns = await indexerClient + * .searchForTransactions() + * .applicationID(appId) + * .do(); + * ``` + * + * @param applicationID + * @category query + */ applicationID(applicationID: number) { this.query['application-id'] = applicationID; return this; diff --git a/src/dryrun.ts b/src/dryrun.ts index e000fbd05..f80a04c3b 100644 --- a/src/dryrun.ts +++ b/src/dryrun.ts @@ -1,16 +1,20 @@ import AlgodClient from './client/v2/algod/algod'; import { + AccountStateDelta, Application, ApplicationParams, ApplicationStateSchema, DryrunRequest, DryrunSource, + EvalDeltaKeyValue, + TealValue, } from './client/v2/algod/models/types'; import { SignedTransaction } from './transaction'; import { TransactionType } from './types/transactions'; import { encodeAddress, getApplicationAddress } from './encoding/address'; const defaultAppId = 1380011588; +const defaultMaxWidth = 30; // When writing the DryrunRequest object as msgpack the output needs to be the byte arrays not b64 string interface AppParamsWithPrograms { @@ -76,7 +80,12 @@ export async function createDryrun({ if (t.txn.appAccounts) accts.push(...t.txn.appAccounts.map((a) => encodeAddress(a.publicKey))); - if (t.txn.appForeignApps) apps.push(...t.txn.appForeignApps); + if (t.txn.appForeignApps) { + apps.push(...t.txn.appForeignApps); + accts.push( + ...t.txn.appForeignApps.map((aidx) => getApplicationAddress(aidx)) + ); + } if (t.txn.appForeignAssets) assets.push(...t.txn.appForeignAssets); @@ -167,3 +176,294 @@ export async function createDryrun({ sources, }); } + +interface StackValueResponse { + type: number; + bytes: string; + uint: number; +} + +class DryrunStackValue { + type: number = 0; + bytes: string = ''; + uint: number = 0; + + constructor(sv: StackValueResponse) { + this.type = sv.type; + this.bytes = sv.bytes; + this.uint = sv.uint; + } + + toString(): string { + if (this.type === 1) { + return `0x${Buffer.from(this.bytes, 'base64').toString('hex')}`; + } + return this.uint.toString(); + } +} + +interface DryrunTraceLineResponse { + error: string; + line: number; + pc: number; + scratch: TealValue[]; + stack: StackValueResponse[]; +} + +class DryrunTraceLine { + error: string = ''; + line: number = 0; + pc: number = 0; + scratch: TealValue[] = []; + stack: DryrunStackValue[] = []; + + constructor(line: DryrunTraceLineResponse) { + this.error = line.error === undefined ? '' : line.error; + this.line = line.line; + this.pc = line.pc; + this.scratch = line.scratch; + this.stack = line.stack.map( + (sv: StackValueResponse) => new DryrunStackValue(sv) + ); + } +} + +class DryrunTrace { + trace: DryrunTraceLine[] = []; + constructor(t: DryrunTraceLineResponse[]) { + if (t === undefined) return; + this.trace = t.map((line) => new DryrunTraceLine(line)); + } +} + +interface DryrunTransactionResultResponse { + disassembly: string[]; + appCallMessages: string[] | undefined; + localDeltas: AccountStateDelta[] | undefined; + globalDelta: EvalDeltaKeyValue[] | undefined; + cost: number | undefined; + logicSigMessages: string[] | undefined; + logicSigDisassembly: string[] | undefined; + logs: string[] | undefined; + appCallTrace: DryrunTrace | undefined; + logicSigTrace: DryrunTrace | undefined; +} + +interface StackPrinterConfig { + maxValueWidth: number | undefined; + topOfStackFirst: boolean | undefined; +} + +function truncate(str: string, maxValueWidth: number): string { + if (str.length > maxValueWidth && maxValueWidth > 0) { + return `${str.slice(0, maxValueWidth)}...`; + } + return str; +} + +function scratchToString( + prevScratch: TealValue[], + currScratch: TealValue[] +): string { + if (currScratch.length === 0) return ''; + + let newScratchIdx = null; + for (let idx = 0; idx < currScratch.length; idx++) { + if (idx > prevScratch.length) { + newScratchIdx = idx; + continue; + } + + if (JSON.stringify(prevScratch[idx]) !== JSON.stringify(currScratch[idx])) { + newScratchIdx = idx; + } + } + + if (newScratchIdx == null) return ''; + + const newScratch = currScratch[newScratchIdx]; + if (newScratch.bytes.length > 0) { + return `${newScratchIdx} = 0x${Buffer.from( + newScratch.bytes, + 'base64' + ).toString('hex')}`; + } + return `${newScratchIdx} = ${newScratch.uint.toString()}`; +} + +function stackToString(stack: DryrunStackValue[], reverse: boolean): string { + const svs = reverse ? stack.reverse() : stack; + return `[${svs + .map((sv: DryrunStackValue) => { + switch (sv.type) { + case 1: + return `0x${Buffer.from(sv.bytes, 'base64').toString('hex')}`; + case 2: + return `${sv.uint.toString()}`; + default: + return ''; + } + }) + .join(', ')}]`; +} + +class DryrunTransactionResult { + disassembly: string[] = []; + appCallMessages: string[] | undefined = []; + localDeltas: AccountStateDelta[] | undefined = []; + globalDelta: EvalDeltaKeyValue[] | undefined = []; + cost: number | undefined = 0; + logicSigMessages: string[] | undefined = []; + logicSigDisassembly: string[] | undefined = []; + logs: string[] | undefined = []; + + appCallTrace: DryrunTrace | undefined = undefined; + logicSigTrace: DryrunTrace | undefined = undefined; + + required = ['disassembly']; + optionals = [ + 'app-call-messages', + 'local-deltas', + 'global-delta', + 'cost', + 'logic-sig-messages', + 'logic-sig-disassembly', + 'logs', + ]; + + traces = ['app-call-trace', 'logic-sig-trace']; + + constructor(dtr: DryrunTransactionResultResponse) { + this.disassembly = dtr.disassembly; + this.appCallMessages = dtr['app-call-messages']; + this.localDeltas = dtr['local-deltas']; + this.globalDelta = dtr['global-delta']; + this.cost = dtr.cost; + this.logicSigMessages = dtr['logic-sig-messages']; + this.logicSigDisassembly = dtr['logic-sig-disassembly']; + this.logs = dtr.logs; + this.appCallTrace = new DryrunTrace(dtr['app-call-trace']); + this.logicSigTrace = new DryrunTrace(dtr['logic-sig-trace']); + } + + appCallRejected(): boolean { + return ( + this.appCallMessages !== undefined && + this.appCallMessages.includes('REJECT') + ); + } + + logicSigRejected(): boolean { + return ( + this.logicSigMessages !== undefined && + this.logicSigMessages.includes('REJECT') + ); + } + + static trace( + drt: DryrunTrace, + disassembly: string[], + spc: StackPrinterConfig + ): string { + let maxWidth = defaultMaxWidth; + if (spc.maxValueWidth === undefined) maxWidth = spc.maxValueWidth; + + // Create the array of arrays, each sub array contains N columns + const lines = [['pc#', 'ln#', 'source', 'scratch', 'stack']]; + for (let idx = 0; idx < drt.trace.length; idx++) { + const { line, error, pc, scratch, stack } = drt.trace[idx]; + + const currScratch = scratch !== undefined ? scratch : []; + const prevScratch = + idx > 0 && drt.trace[idx - 1].scratch !== undefined + ? drt.trace[idx - 1].scratch + : []; + + const src = error === '' ? disassembly[line] : `!! ${error} !!`; + + lines.push([ + pc.toString().padEnd(3, ' '), + line.toString().padEnd(3, ' '), + truncate(src, maxWidth), + truncate(scratchToString(prevScratch, currScratch), maxWidth), + truncate(stackToString(stack, spc.topOfStackFirst), maxWidth), + ]); + } + + // Get the max length for each column + const maxLengths = lines.reduce((prev, curr) => { + const newVal = new Array(lines[0].length).fill(0); + for (let idx = 0; idx < prev.length; idx++) { + newVal[idx] = + curr[idx].length > prev[idx] ? curr[idx].length : prev[idx]; + } + return newVal; + }, new Array(lines[0].length).fill(0)); + + return `${lines + .map((line) => + line + .map((v, idx) => v.padEnd(maxLengths[idx] + 1, ' ')) + .join('|') + .trim() + ) + .join('\n')}\n`; + } + + appTrace(spc?: StackPrinterConfig): string { + if (this.appCallTrace === undefined || !this.disassembly) return ''; + + let conf = spc; + if (spc === undefined) + conf = { + maxValueWidth: defaultMaxWidth, + topOfStackFirst: false, + } as StackPrinterConfig; + + return DryrunTransactionResult.trace( + this.appCallTrace, + this.disassembly, + conf + ); + } + + lsigTrace(spc?: StackPrinterConfig): string { + if ( + this.logicSigTrace === undefined || + this.logicSigDisassembly === undefined + ) + return ''; + + let conf = spc; + if (spc === undefined) + conf = { + maxValueWidth: defaultMaxWidth, + topOfStackFirst: true, + } as StackPrinterConfig; + + return DryrunTransactionResult.trace( + this.logicSigTrace, + this.logicSigDisassembly, + conf + ); + } +} + +interface DryrunResultResponse { + ['error']: string; + ['protocol-version']: string; + ['txns']: DryrunTransactionResultResponse[]; +} + +export class DryrunResult { + error: string = ''; + protocolVersion: string = ''; + txns: DryrunTransactionResult[] = []; + constructor(drrResp: DryrunResultResponse) { + this.error = drrResp.error; + this.protocolVersion = drrResp['protocol-version']; + this.txns = drrResp.txns.map( + (txn: DryrunTransactionResultResponse) => new DryrunTransactionResult(txn) + ); + } +} diff --git a/tests/cucumber/steps/steps.js b/tests/cucumber/steps/steps.js index 71dc749ff..ff6716232 100644 --- a/tests/cucumber/steps/steps.js +++ b/tests/cucumber/steps/steps.js @@ -5265,6 +5265,22 @@ module.exports = function getSteps(options) { } ); + Given( + 'a dryrun response file {string} and a transaction at index {string}', + async function (drrFile, txId) { + const drContents = await loadResource(drrFile); + const js = parseJSON(drContents); + const drr = new algosdk.DryrunResult(js); + this.txtrace = drr.txns[parseInt(txId)]; + } + ); + + Then('calling app trace produces {string}', async function (expected) { + const traceString = this.txtrace.appTrace(); + const expectedString = (await loadResource(expected)).toString(); + assert.equal(traceString, expectedString); + }); + if (!options.ignoreReturn) { return steps; }