├── .npmrc ├── dist └── esm │ └── package.json ├── .dockerignore ├── examples ├── lsig │ ├── simple.teal │ └── sample_arg.teal ├── application │ ├── clear.teal │ ├── approval.teal │ └── approval_refactored.teal ├── calculator │ ├── clear.teal │ ├── contract.json │ └── approval.teal ├── .eslintrc.json ├── README.md ├── smoke_test.sh ├── debug.ts ├── overview.ts ├── participation.ts ├── atomics.ts ├── block_fetcher │ └── index.ts ├── lsig.ts ├── indexer.ts ├── codec.ts ├── kmd.ts ├── atc.ts └── accounts.ts ├── CODEOWNERS ├── .prettierrc.json ├── src ├── types │ ├── transactions │ │ ├── index.ts │ │ └── encoded.ts │ ├── account.ts │ ├── intDecoding.ts │ └── utils.ts ├── index.ts ├── client │ ├── v2 │ │ ├── algod │ │ │ ├── index.ts │ │ │ ├── ready.ts │ │ │ ├── genesis.ts │ │ │ ├── healthCheck.ts │ │ │ ├── supply.ts │ │ │ ├── status.ts │ │ │ ├── getSyncRound.ts │ │ │ ├── versions.ts │ │ │ ├── getAssetByID.ts │ │ │ ├── stateproof.ts │ │ │ ├── getBlockOffsetTimestamp.ts │ │ │ ├── getApplicationByID.ts │ │ │ ├── lightBlockHeaderProof.ts │ │ │ ├── getBlockHash.ts │ │ │ ├── getBlockTxids.ts │ │ │ ├── statusAfterBlock.ts │ │ │ ├── unsetSyncRound.ts │ │ │ ├── block.ts │ │ │ ├── getLedgerStateDeltaForTransactionGroup.ts │ │ │ ├── getLedgerStateDelta.ts │ │ │ ├── setSyncRound.ts │ │ │ ├── setBlockOffsetTimestamp.ts │ │ │ ├── accountAssetInformation.ts │ │ │ ├── pendingTransactions.ts │ │ │ ├── pendingTransactionInformation.ts │ │ │ ├── accountApplicationInformation.ts │ │ │ ├── getTransactionGroupLedgerStateDeltasForRound.ts │ │ │ ├── pendingTransactionsByAddress.ts │ │ │ ├── dryrun.ts │ │ │ ├── accountInformation.ts │ │ │ ├── getTransactionProof.ts │ │ │ ├── getApplicationBoxByName.ts │ │ │ ├── disassemble.ts │ │ │ ├── compile.ts │ │ │ ├── simulateTransaction.ts │ │ │ ├── getApplicationBoxes.ts │ │ │ ├── suggestedParams.ts │ │ │ └── sendRawTransaction.ts │ │ ├── indexer │ │ │ ├── index.ts │ │ │ ├── makeHealthCheck.ts │ │ │ ├── lookupTransactionByID.ts │ │ │ ├── lookupBlock.ts │ │ │ ├── lookupApplicationBoxByIDandName.ts │ │ │ ├── lookupAssetByID.ts │ │ │ ├── lookupApplications.ts │ │ │ ├── searchForApplicationBoxes.ts │ │ │ ├── lookupAccountByID.ts │ │ │ └── searchForApplications.ts │ │ ├── untypedmodel.ts │ │ ├── serviceClient.ts │ │ └── jsonrequest.ts │ ├── index.ts │ └── baseHTTPClient.ts ├── abi │ ├── index.ts │ ├── reference.ts │ ├── event.ts │ ├── interface.ts │ ├── transaction.ts │ └── contract.ts ├── account.ts ├── convert.ts ├── encoding │ ├── schema │ │ ├── index.ts │ │ ├── uint64.ts │ │ ├── untyped.ts │ │ ├── boolean.ts │ │ ├── string.ts │ │ ├── address.ts │ │ ├── array.ts │ │ ├── optional.ts │ │ ├── binarystring.ts │ │ ├── blockhash.ts │ │ └── bytearray.ts │ ├── bigint.ts │ ├── binarydata.ts │ └── uint64.ts ├── boxStorage.ts ├── group.ts ├── nacl │ └── naclWrappers.ts ├── wait.ts ├── signing.ts ├── logic │ └── sourcemap.ts └── heartbeat.ts ├── .huskyrc.js ├── .vscode ├── extensions.json ├── settings.json └── launch.json ├── tests ├── compile │ ├── tsconfig.json │ └── basic.ts ├── cucumber │ ├── cucumber.js │ ├── browser │ │ ├── webpack.config.js │ │ ├── index.html │ │ └── test.js │ ├── integration.tags │ ├── unit.tags │ └── docker │ │ └── Dockerfile ├── resources │ ├── stateproof.msgp │ └── groupdelta-betanet_23963123_2.msgp ├── browser │ └── index.html └── 1.Mnemonics_test.ts ├── .lintstagedrc.js ├── tsconfig-browser.json ├── .gitattributes ├── .prettierignore ├── tsconfig-cjs.json ├── typedoc.config.json ├── tsconfig-esm.json ├── tsconfig.json ├── .editorconfig ├── .github ├── release.yml ├── workflows │ ├── codegen.yml │ └── pr-type-category.yml └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── tsdoc.json ├── .gitignore ├── .test-env ├── LICENSE ├── webpack.config.js ├── FAQ.md ├── Makefile ├── .eslintrc.js ├── scripts └── bump_version.py ├── package.json └── test-harness.sh /.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict=true 2 | -------------------------------------------------------------------------------- /dist/esm/package.json: -------------------------------------------------------------------------------- 1 | {"type": "module"} 2 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | docs/ 4 | -------------------------------------------------------------------------------- /examples/lsig/simple.teal: -------------------------------------------------------------------------------- 1 | #pragma version 5 2 | int 1 3 | return -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | .github/ @algorand/devops 2 | .circleci/ @algorand/devops 3 | -------------------------------------------------------------------------------- /examples/application/clear.teal: -------------------------------------------------------------------------------- 1 | #pragma version 4 2 | int 1 3 | return -------------------------------------------------------------------------------- /examples/calculator/clear.teal: -------------------------------------------------------------------------------- 1 | #pragma version 8 2 | pushint 0 // 0 3 | return -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "es5" 4 | } 5 | -------------------------------------------------------------------------------- /examples/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "no-console": "off" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /examples/lsig/sample_arg.teal: -------------------------------------------------------------------------------- 1 | #pragma version 5 2 | arg_0 3 | btoi 4 | int 123 5 | == -------------------------------------------------------------------------------- /src/types/transactions/index.ts: -------------------------------------------------------------------------------- 1 | export * from './base.js'; 2 | export * from './encoded.js'; 3 | -------------------------------------------------------------------------------- /.huskyrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | hooks: { 3 | 'pre-commit': 'lint-staged', 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["esbenp.prettier-vscode", "dbaeumer.vscode-eslint"] 3 | } 4 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import * as algosdk from './main.js'; 2 | 3 | export * from './main.js'; 4 | export default algosdk; 5 | -------------------------------------------------------------------------------- /src/client/v2/algod/index.ts: -------------------------------------------------------------------------------- 1 | // ALGOD 2 | export { AlgodClient } from './algod.js'; 3 | export * from './models/types.js'; 4 | -------------------------------------------------------------------------------- /tests/compile/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "noEmit": true 4 | }, 5 | "include": ["./basic.ts"] 6 | } 7 | -------------------------------------------------------------------------------- /tests/cucumber/cucumber.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | default: '--format-options \'{"snippetInterface": "synchronous"}\'', 3 | }; 4 | -------------------------------------------------------------------------------- /tests/resources/stateproof.msgp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hardcoding-1992/js-algorand-sdk/HEAD/tests/resources/stateproof.msgp -------------------------------------------------------------------------------- /src/client/v2/indexer/index.ts: -------------------------------------------------------------------------------- 1 | // Indexer 2 | export { IndexerClient } from './indexer.js'; 3 | export * from './models/types.js'; 4 | -------------------------------------------------------------------------------- /.lintstagedrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | '*.{js,ts,md,json,yml}': 'prettier --write', 3 | '*.{js,ts}': 'eslint --cache --fix', 4 | }; 5 | -------------------------------------------------------------------------------- /tsconfig-browser.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./dist/browser" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | src/client/v2/algod/models/types.ts linguist-generated=true 2 | src/client/v2/indexer/models/types.ts linguist-generated=true 3 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | dist 2 | docs 3 | tests/cucumber/features 4 | tests/cucumber/browser/build 5 | tests/browser/bundle.* 6 | .github 7 | CODE_OF_CONDUCT.md 8 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.defaultFormatter": "esbenp.prettier-vscode", 3 | "editor.formatOnSave": true, 4 | "editor.formatOnPaste": true 5 | } 6 | -------------------------------------------------------------------------------- /tests/compile/basic.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /* eslint-disable */ 3 | 4 | import * as algosdk from '../../dist/esm/index'; 5 | -------------------------------------------------------------------------------- /tsconfig-cjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./dist/cjs", 5 | "module": "CommonJS" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /typedoc.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "excludeExternals": true, 3 | "entryPoints": ["./src/main.ts"], 4 | "entryPointStrategy": "expand", 5 | "out": "docs" 6 | } 7 | -------------------------------------------------------------------------------- /tests/resources/groupdelta-betanet_23963123_2.msgp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hardcoding-1992/js-algorand-sdk/HEAD/tests/resources/groupdelta-betanet_23963123_2.msgp -------------------------------------------------------------------------------- /tsconfig-esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./dist/esm", 5 | "declaration": true, 6 | "declarationDir": "./dist/types" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/abi/index.ts: -------------------------------------------------------------------------------- 1 | export * from './abi_type.js'; 2 | export * from './contract.js'; 3 | export * from './interface.js'; 4 | export * from './method.js'; 5 | export * from './transaction.js'; 6 | export * from './reference.js'; 7 | -------------------------------------------------------------------------------- /src/client/index.ts: -------------------------------------------------------------------------------- 1 | // Generics 2 | export { default as JSONRequest } from './v2/jsonrequest.js'; 3 | export { default as ServiceClient } from './v2/serviceClient.js'; 4 | export * from './baseHTTPClient.js'; 5 | export * from './urlTokenBaseHTTPClient.js'; 6 | export * from './client.js'; 7 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | ## Algorand JavaScript SDK Examples 2 | 3 | This directory contains examples of how to use the Algorand JavaScript SDK. 4 | 5 | Assuming a sandbox node is running locally, any example can be run with the following command: 6 | 7 | ```sh 8 | ts-node .ts 9 | ``` 10 | -------------------------------------------------------------------------------- /tests/cucumber/browser/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | mode: 'development', 5 | entry: path.resolve(__dirname, 'test.js'), 6 | output: { 7 | filename: 'test.js', 8 | path: path.resolve(__dirname, 'build'), 9 | }, 10 | devtool: 'source-map', 11 | optimization: { 12 | minimize: false, 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["es5", "es2015.promise", "dom", "es2015"], 4 | "outDir": "./dist", 5 | "allowJs": true, 6 | "target": "es2020", 7 | "moduleResolution": "node", 8 | "resolveJsonModule": true, 9 | "esModuleInterop": true, 10 | "sourceMap": true, 11 | "strict": true 12 | }, 13 | "include": ["./src"] 14 | } 15 | -------------------------------------------------------------------------------- /src/types/account.ts: -------------------------------------------------------------------------------- 1 | import { Address } from '../encoding/address.js'; 2 | 3 | /** 4 | * An Algorand account object. 5 | * 6 | * Contains an Algorand address and secret key. 7 | */ 8 | export default interface Account { 9 | /** 10 | * Algorand address 11 | */ 12 | addr: Address; 13 | 14 | /** 15 | * Secret key belonging to the Algorand address 16 | */ 17 | sk: Uint8Array; 18 | } 19 | -------------------------------------------------------------------------------- /tests/cucumber/integration.tags: -------------------------------------------------------------------------------- 1 | @abi 2 | @algod 3 | @applications.boxes 4 | @applications.verified 5 | @assets 6 | @c2c 7 | @compile 8 | @compile.disassemble 9 | @compile.sourcemap 10 | @dryrun 11 | @kmd 12 | @rekey_v1 13 | @send 14 | @send.keyregtxn 15 | @simulate 16 | @simulate.lift_log_limits 17 | @simulate.extra_opcode_budget 18 | @simulate.exec_trace_with_stack_scratch 19 | @simulate.exec_trace_with_state_change_and_hash 20 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # top-most EditorConfig file 2 | root = true 3 | 4 | # Unix-style newlines with a newline ending every file 5 | [*] 6 | end_of_line = lf 7 | insert_final_newline = true 8 | 9 | # Set JavaScript file rules 10 | [*.js] 11 | charset = utf-8 12 | indent_style = space 13 | indent_size = 2 14 | 15 | # Matches the exact files either package.json or .travis.yml 16 | [{package.json,.travis.yml}] 17 | indent_style = space 18 | indent_size = 2 19 | -------------------------------------------------------------------------------- /src/account.ts: -------------------------------------------------------------------------------- 1 | import * as nacl from './nacl/naclWrappers.js'; 2 | import { Address } from './encoding/address.js'; 3 | import Account from './types/account.js'; 4 | 5 | /** 6 | * generateAccount returns a new Algorand address and its corresponding secret key 7 | */ 8 | export default function generateAccount(): Account { 9 | const keys = nacl.keyPair(); 10 | const addr = new Address(keys.publicKey); 11 | return { addr, sk: keys.secretKey }; 12 | } 13 | -------------------------------------------------------------------------------- /src/client/v2/algod/ready.ts: -------------------------------------------------------------------------------- 1 | import JSONRequest from '../jsonrequest.js'; 2 | import { HTTPClientResponse } from '../../client.js'; 3 | 4 | export default class Ready extends JSONRequest { 5 | // eslint-disable-next-line class-methods-use-this 6 | path() { 7 | return `/ready`; 8 | } 9 | 10 | // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars 11 | prepare(_response: HTTPClientResponse): void {} 12 | } 13 | -------------------------------------------------------------------------------- /.github/release.yml: -------------------------------------------------------------------------------- 1 | changelog: 2 | exclude: 3 | labels: 4 | - Skip-Release-Notes 5 | categories: 6 | - title: Bugfixes 7 | labels: 8 | - Bug-Fix 9 | - title: New Features 10 | labels: 11 | - New Feature 12 | - title: Enhancements 13 | labels: 14 | - Enhancement 15 | - title: Not Yet Enabled 16 | labels: 17 | - Not-Yet-Enabled 18 | - title: Other 19 | labels: 20 | - "*" 21 | -------------------------------------------------------------------------------- /src/client/v2/algod/genesis.ts: -------------------------------------------------------------------------------- 1 | import JSONRequest from '../jsonrequest.js'; 2 | import { HTTPClientResponse } from '../../client.js'; 3 | 4 | export default class Genesis extends JSONRequest { 5 | // eslint-disable-next-line class-methods-use-this 6 | path() { 7 | return '/genesis'; 8 | } 9 | 10 | // eslint-disable-next-line class-methods-use-this 11 | prepare(response: HTTPClientResponse): string { 12 | return response.getJSONText(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/cucumber/browser/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Algosdk Browser Testing 5 | 9 | 10 | 11 | 12 | 13 | 14 |

Algosdk Browser Testing

15 | 16 | 17 | -------------------------------------------------------------------------------- /src/client/v2/algod/healthCheck.ts: -------------------------------------------------------------------------------- 1 | import JSONRequest from '../jsonrequest.js'; 2 | import { HTTPClientResponse } from '../../client.js'; 3 | 4 | /** 5 | * healthCheck returns an empty object iff the node is running 6 | */ 7 | export default class HealthCheck extends JSONRequest { 8 | // eslint-disable-next-line class-methods-use-this 9 | path() { 10 | return '/health'; 11 | } 12 | 13 | // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars 14 | prepare(_response: HTTPClientResponse): void {} 15 | } 16 | -------------------------------------------------------------------------------- /.github/workflows/codegen.yml: -------------------------------------------------------------------------------- 1 | name: "SDK Code Generation" 2 | on: 3 | schedule: 4 | - cron: '20 23 * * *' 5 | permissions: 6 | contents: write 7 | pull-requests: write 8 | jobs: 9 | generate_and_pr: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Check out repository 13 | uses: actions/checkout@v3 14 | - name: Generate and PR 15 | uses: algorand/generator/.github/actions/sdk-codegen/@master 16 | with: 17 | args: "-k JS" 18 | env: 19 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 20 | -------------------------------------------------------------------------------- /src/abi/reference.ts: -------------------------------------------------------------------------------- 1 | export enum ABIReferenceType { 2 | /** 3 | * Account reference type 4 | */ 5 | account = 'account', 6 | 7 | /** 8 | * Application reference type 9 | */ 10 | application = 'application', 11 | 12 | /** 13 | * Asset reference type 14 | */ 15 | asset = 'asset', 16 | } 17 | 18 | export function abiTypeIsReference(type: any): type is ABIReferenceType { 19 | return ( 20 | type === ABIReferenceType.account || 21 | type === ABIReferenceType.application || 22 | type === ABIReferenceType.asset 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /tsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", 3 | "tagDefinitions": [ 4 | { 5 | "tagName": "@category", 6 | "syntaxKind": "block" 7 | }, 8 | { 9 | "tagName": "@ignore", 10 | "syntaxKind": "modifier" 11 | } 12 | ], 13 | "supportForTags": { 14 | "@remarks": true, 15 | "@ignore": true, 16 | "@throws": true, 17 | "@returns": true, 18 | "@param": true, 19 | "@category": true, 20 | "@deprecated": true, 21 | "@link": true 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist/* 2 | !dist/esm 3 | dist/esm/* 4 | !dist/esm/package.json 5 | 6 | .DS_Store 7 | 8 | .idea/ 9 | # Webstorm 10 | *.iml 11 | .vscode/* 12 | !.vscode/settings.json 13 | !.vscode/extensions.json 14 | !.vscode/launch.json 15 | 16 | # npm 17 | node_modules/ 18 | 19 | # Testing files 20 | *.feature 21 | temp 22 | 23 | # Environment information 24 | examples/.env 25 | 26 | test-harness/ 27 | tests/cucumber/features/ 28 | tests/cucumber/browser/build 29 | tests/browser/bundle.* 30 | 31 | # Builds 32 | docs/ 33 | built/ 34 | 35 | # Caches 36 | .eslintcache 37 | -------------------------------------------------------------------------------- /src/abi/event.ts: -------------------------------------------------------------------------------- 1 | /** [ARC-28](https://arc.algorand.foundation/ARCs/arc-0028) event description */ 2 | export interface ARC28Event { 3 | /** The name of the event */ 4 | name: string; 5 | /** Optional, user-friendly description for the event */ 6 | desc?: string; 7 | /** The arguments of the event, in order */ 8 | args: Array<{ 9 | /** The type of the argument */ 10 | type: string; 11 | /** Optional, user-friendly name for the argument */ 12 | name?: string; 13 | /** Optional, user-friendly description for the argument */ 14 | desc?: string; 15 | }>; 16 | } 17 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F514 Feature Request" 3 | about: Suggestions for how we can improve the algorand platform. 4 | title: '' 5 | labels: new-feature-request 6 | assignees: '' 7 | --- 8 | 9 | ## Problem 10 | 11 | 12 | 13 | ## Solution 14 | 15 | 16 | 17 | ## Dependencies 18 | 19 | 20 | 21 | ## Urgency 22 | 23 | 24 | -------------------------------------------------------------------------------- /.test-env: -------------------------------------------------------------------------------- 1 | # Configs for testing repo download: 2 | SDK_TESTING_URL="https://github.com/algorand/algorand-sdk-testing" 3 | SDK_TESTING_BRANCH="master" 4 | SDK_TESTING_HARNESS="test-harness" 5 | 6 | INSTALL_ONLY=0 7 | 8 | VERBOSE_HARNESS=1 9 | 10 | # WARNING: If set to 1, new features will be LOST when downloading the test harness. 11 | # REGARDLESS: modified features are ALWAYS overwritten. 12 | REMOVE_LOCAL_FEATURES=0 13 | 14 | # WARNING: Be careful when turning on the next variable. 15 | # In that case you'll need to provide all variables expected by `algorand-sdk-testing`'s `.env` 16 | OVERWRITE_TESTING_ENVIRONMENT=0 17 | -------------------------------------------------------------------------------- /src/client/v2/algod/supply.ts: -------------------------------------------------------------------------------- 1 | import JSONRequest from '../jsonrequest.js'; 2 | import { HTTPClientResponse } from '../../client.js'; 3 | import { decodeJSON } from '../../../encoding/encoding.js'; 4 | import { SupplyResponse } from './models/types.js'; 5 | 6 | export default class Supply extends JSONRequest { 7 | // eslint-disable-next-line class-methods-use-this 8 | path() { 9 | return '/v2/ledger/supply'; 10 | } 11 | 12 | // eslint-disable-next-line class-methods-use-this 13 | prepare(response: HTTPClientResponse): SupplyResponse { 14 | return decodeJSON(response.getJSONText(), SupplyResponse); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/client/v2/algod/status.ts: -------------------------------------------------------------------------------- 1 | import JSONRequest from '../jsonrequest.js'; 2 | import { HTTPClientResponse } from '../../client.js'; 3 | import { decodeJSON } from '../../../encoding/encoding.js'; 4 | import { NodeStatusResponse } from './models/types.js'; 5 | 6 | export default class Status extends JSONRequest { 7 | // eslint-disable-next-line class-methods-use-this 8 | path() { 9 | return '/v2/status'; 10 | } 11 | 12 | // eslint-disable-next-line class-methods-use-this 13 | prepare(response: HTTPClientResponse): NodeStatusResponse { 14 | return decodeJSON(response.getJSONText(), NodeStatusResponse); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/client/v2/algod/getSyncRound.ts: -------------------------------------------------------------------------------- 1 | import JSONRequest from '../jsonrequest.js'; 2 | import { HTTPClientResponse } from '../../client.js'; 3 | import { decodeJSON } from '../../../encoding/encoding.js'; 4 | import { GetSyncRoundResponse } from './models/types.js'; 5 | 6 | export default class GetSyncRound extends JSONRequest { 7 | // eslint-disable-next-line class-methods-use-this 8 | path() { 9 | return `/v2/ledger/sync`; 10 | } 11 | 12 | // eslint-disable-next-line class-methods-use-this 13 | prepare(response: HTTPClientResponse): GetSyncRoundResponse { 14 | return decodeJSON(response.getJSONText(), GetSyncRoundResponse); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/client/v2/algod/versions.ts: -------------------------------------------------------------------------------- 1 | import JSONRequest from '../jsonrequest.js'; 2 | import { HTTPClientResponse } from '../../client.js'; 3 | import { decodeJSON } from '../../../encoding/encoding.js'; 4 | import { Version } from './models/types.js'; 5 | 6 | /** 7 | * retrieves the VersionResponse from the running node 8 | */ 9 | export default class Versions extends JSONRequest { 10 | // eslint-disable-next-line class-methods-use-this 11 | path() { 12 | return '/versions'; 13 | } 14 | 15 | // eslint-disable-next-line class-methods-use-this 16 | prepare(response: HTTPClientResponse): Version { 17 | return decodeJSON(response.getJSONText(), Version); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/browser/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Algosdk Mocha Browser Testing 5 | 6 | 7 | 8 | 9 |

Algosdk Mocha Browser Testing

10 |
11 | 12 | 13 | 14 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /examples/smoke_test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | export ALGOD_PORT="60000" 4 | export INDEXER_PORT="59999" 5 | export KMD_PORT="60001" 6 | 7 | # Loop over all files in the directory 8 | for file in *; do 9 | # Check if the file ends with ".ts" 10 | if [[ $file == *.ts ]]; then 11 | # Check if the filename is not "utils.ts" 12 | if [[ $file != "utils.ts" ]]; then 13 | # Call the file using `ts-node` 14 | ../node_modules/.bin/tsx "$file" 15 | # Check if the test failed 16 | if [ $? -ne 0 ]; then 17 | echo "Test failed, stopping script" 18 | exit 1 19 | fi 20 | fi 21 | 22 | fi 23 | done 24 | -------------------------------------------------------------------------------- /src/client/v2/algod/getAssetByID.ts: -------------------------------------------------------------------------------- 1 | import JSONRequest from '../jsonrequest.js'; 2 | import { HTTPClient, HTTPClientResponse } from '../../client.js'; 3 | import { decodeJSON } from '../../../encoding/encoding.js'; 4 | import { Asset } from './models/types.js'; 5 | 6 | export default class GetAssetByID extends JSONRequest { 7 | private index: bigint; 8 | 9 | constructor(c: HTTPClient, index: number | bigint) { 10 | super(c); 11 | this.index = BigInt(index); 12 | } 13 | 14 | path() { 15 | return `/v2/assets/${this.index}`; 16 | } 17 | 18 | // eslint-disable-next-line class-methods-use-this 19 | prepare(response: HTTPClientResponse): Asset { 20 | return decodeJSON(response.getJSONText(), Asset); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/client/v2/algod/stateproof.ts: -------------------------------------------------------------------------------- 1 | import JSONRequest from '../jsonrequest.js'; 2 | import { HTTPClient, HTTPClientResponse } from '../../client.js'; 3 | import { decodeJSON } from '../../../encoding/encoding.js'; 4 | import { StateProof as SP } from './models/types.js'; 5 | 6 | export default class StateProof extends JSONRequest { 7 | private round: bigint; 8 | 9 | constructor(c: HTTPClient, round: number | bigint) { 10 | super(c); 11 | this.round = BigInt(round); 12 | } 13 | 14 | path() { 15 | return `/v2/stateproofs/${this.round}`; 16 | } 17 | 18 | // eslint-disable-next-line class-methods-use-this 19 | prepare(response: HTTPClientResponse): SP { 20 | return decodeJSON(response.getJSONText(), SP); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/client/v2/algod/getBlockOffsetTimestamp.ts: -------------------------------------------------------------------------------- 1 | import JSONRequest from '../jsonrequest.js'; 2 | import { HTTPClientResponse } from '../../client.js'; 3 | import { decodeJSON } from '../../../encoding/encoding.js'; 4 | import { GetBlockTimeStampOffsetResponse } from './models/types.js'; 5 | 6 | export default class GetBlockOffsetTimestamp extends JSONRequest { 7 | // eslint-disable-next-line class-methods-use-this 8 | path() { 9 | return `/v2/devmode/blocks/offset`; 10 | } 11 | 12 | // eslint-disable-next-line class-methods-use-this 13 | prepare(response: HTTPClientResponse): GetBlockTimeStampOffsetResponse { 14 | return decodeJSON(response.getJSONText(), GetBlockTimeStampOffsetResponse); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/client/v2/algod/getApplicationByID.ts: -------------------------------------------------------------------------------- 1 | import JSONRequest from '../jsonrequest.js'; 2 | import { HTTPClient, HTTPClientResponse } from '../../client.js'; 3 | import { decodeJSON } from '../../../encoding/encoding.js'; 4 | import { Application } from './models/types.js'; 5 | 6 | export default class GetApplicationByID extends JSONRequest { 7 | private index: bigint; 8 | 9 | constructor(c: HTTPClient, index: number | bigint) { 10 | super(c); 11 | this.index = BigInt(index); 12 | } 13 | 14 | path() { 15 | return `/v2/applications/${this.index}`; 16 | } 17 | 18 | // eslint-disable-next-line class-methods-use-this 19 | prepare(response: HTTPClientResponse): Application { 20 | return decodeJSON(response.getJSONText(), Application); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/client/v2/algod/lightBlockHeaderProof.ts: -------------------------------------------------------------------------------- 1 | import JSONRequest from '../jsonrequest.js'; 2 | import { HTTPClient, HTTPClientResponse } from '../../client.js'; 3 | import { decodeJSON } from '../../../encoding/encoding.js'; 4 | import { LightBlockHeaderProof as LBHP } from './models/types.js'; 5 | 6 | export default class LightBlockHeaderProof extends JSONRequest { 7 | private round: bigint; 8 | 9 | constructor(c: HTTPClient, round: number | bigint) { 10 | super(c); 11 | this.round = BigInt(round); 12 | } 13 | 14 | path() { 15 | return `/v2/blocks/${this.round}/lightheader/proof`; 16 | } 17 | 18 | // eslint-disable-next-line class-methods-use-this 19 | prepare(response: HTTPClientResponse): LBHP { 20 | return decodeJSON(response.getJSONText(), LBHP); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/client/v2/algod/getBlockHash.ts: -------------------------------------------------------------------------------- 1 | import JSONRequest from '../jsonrequest.js'; 2 | import { HTTPClient, HTTPClientResponse } from '../../client.js'; 3 | import { decodeJSON } from '../../../encoding/encoding.js'; 4 | import { BlockHashResponse } from './models/types.js'; 5 | 6 | export default class GetBlockHash extends JSONRequest { 7 | private round: bigint; 8 | 9 | constructor(c: HTTPClient, roundNumber: number | bigint) { 10 | super(c); 11 | this.round = BigInt(roundNumber); 12 | } 13 | 14 | path() { 15 | return `/v2/blocks/${this.round}/hash`; 16 | } 17 | 18 | // eslint-disable-next-line class-methods-use-this 19 | prepare(response: HTTPClientResponse): BlockHashResponse { 20 | return decodeJSON(response.getJSONText(), BlockHashResponse); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/client/v2/algod/getBlockTxids.ts: -------------------------------------------------------------------------------- 1 | import JSONRequest from '../jsonrequest.js'; 2 | import { HTTPClient, HTTPClientResponse } from '../../client.js'; 3 | import { decodeJSON } from '../../../encoding/encoding.js'; 4 | import { BlockTxidsResponse } from './models/types.js'; 5 | 6 | export default class GetBlockTxids extends JSONRequest { 7 | private round: bigint; 8 | 9 | constructor(c: HTTPClient, roundNumber: number | bigint) { 10 | super(c); 11 | this.round = BigInt(roundNumber); 12 | } 13 | 14 | path() { 15 | return `/v2/blocks/${this.round}/txids`; 16 | } 17 | 18 | // eslint-disable-next-line class-methods-use-this 19 | prepare(response: HTTPClientResponse): BlockTxidsResponse { 20 | return decodeJSON(response.getJSONText(), BlockTxidsResponse); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F41C Bug report" 3 | about: Report a reproducible bug. 4 | title: '' 5 | labels: new-bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | ### Subject of the issue 11 | 12 | 13 | 14 | ### Your environment 15 | 16 | 22 | 23 | ### Steps to reproduce 24 | 25 | 1. 26 | 2. 27 | 28 | ### Expected behaviour 29 | 30 | ### Actual behaviour 31 | -------------------------------------------------------------------------------- /src/client/v2/algod/statusAfterBlock.ts: -------------------------------------------------------------------------------- 1 | import JSONRequest from '../jsonrequest.js'; 2 | import { HTTPClient, HTTPClientResponse } from '../../client.js'; 3 | import { decodeJSON } from '../../../encoding/encoding.js'; 4 | import { NodeStatusResponse } from './models/types.js'; 5 | 6 | export default class StatusAfterBlock extends JSONRequest { 7 | private round: bigint; 8 | 9 | constructor(c: HTTPClient, round: number | bigint) { 10 | super(c); 11 | this.round = BigInt(round); 12 | } 13 | 14 | path() { 15 | return `/v2/status/wait-for-block-after/${this.round}`; 16 | } 17 | 18 | // eslint-disable-next-line class-methods-use-this 19 | prepare(response: HTTPClientResponse): NodeStatusResponse { 20 | return decodeJSON(response.getJSONText(), NodeStatusResponse); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/client/v2/algod/unsetSyncRound.ts: -------------------------------------------------------------------------------- 1 | import JSONRequest from '../jsonrequest.js'; 2 | import { HTTPClientResponse } from '../../client.js'; 3 | 4 | export default class UnsetSyncRound extends JSONRequest { 5 | // eslint-disable-next-line class-methods-use-this 6 | path() { 7 | return `/v2/ledger/sync`; 8 | } 9 | 10 | protected executeRequest( 11 | headers?: Record, 12 | customOptions?: Record 13 | ): Promise { 14 | return this.c.delete({ 15 | relativePath: this.path(), 16 | data: undefined, 17 | requestHeaders: headers, 18 | customOptions, 19 | }); 20 | } 21 | 22 | // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars 23 | prepare(_response: HTTPClientResponse): void {} 24 | } 25 | -------------------------------------------------------------------------------- /src/convert.ts: -------------------------------------------------------------------------------- 1 | const MICROALGOS_TO_ALGOS_RATIO = 1e6; 2 | export const INVALID_MICROALGOS_ERROR_MSG = 3 | 'Microalgos should be positive and less than 2^53 - 1.'; 4 | 5 | /** 6 | * microalgosToAlgos converts microalgos to algos 7 | * @param microalgos - number 8 | * @returns number 9 | */ 10 | export function microalgosToAlgos(microalgos: number) { 11 | if (microalgos < 0 || !Number.isSafeInteger(microalgos)) { 12 | throw new Error(INVALID_MICROALGOS_ERROR_MSG); 13 | } 14 | return microalgos / MICROALGOS_TO_ALGOS_RATIO; 15 | } 16 | 17 | /** 18 | * algosToMicroalgos converts algos to microalgos 19 | * @param algos - number 20 | * @returns number 21 | */ 22 | export function algosToMicroalgos(algos: number) { 23 | const microalgos = algos * MICROALGOS_TO_ALGOS_RATIO; 24 | return Math.round(microalgos); 25 | } 26 | -------------------------------------------------------------------------------- /src/client/v2/untypedmodel.ts: -------------------------------------------------------------------------------- 1 | import { Encodable, MsgpackEncodingData } from '../../encoding/encoding.js'; 2 | import { UntypedSchema } from '../../encoding/schema/index.js'; 3 | 4 | export class UntypedValue implements Encodable { 5 | static readonly encodingSchema = new UntypedSchema(); 6 | 7 | public readonly data: MsgpackEncodingData; 8 | 9 | constructor(data: MsgpackEncodingData) { 10 | this.data = data; 11 | } 12 | 13 | // eslint-disable-next-line class-methods-use-this 14 | public getEncodingSchema(): UntypedSchema { 15 | return UntypedValue.encodingSchema; 16 | } 17 | 18 | public toEncodingData(): MsgpackEncodingData { 19 | return this.data; 20 | } 21 | 22 | public static fromEncodingData(data: unknown): UntypedValue { 23 | return new UntypedValue(data as MsgpackEncodingData); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/types/intDecoding.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Configure how integers in JSON response will be decoded. 3 | */ 4 | enum IntDecoding { 5 | /** 6 | * All integers will be decoded as Numbers, meaning any values greater than 7 | * Number.MAX_SAFE_INTEGER will lose precision. 8 | */ 9 | UNSAFE = 'unsafe', 10 | 11 | /** 12 | * All integers will be decoded as Numbers, but if any values are greater than 13 | * Number.MAX_SAFE_INTEGER an error will be thrown. 14 | */ 15 | SAFE = 'safe', 16 | 17 | /** 18 | * Integers will be decoded as Numbers if they are less than or equal to 19 | * Number.MAX_SAFE_INTEGER, otherwise they will be decoded as BigInts. 20 | */ 21 | MIXED = 'mixed', 22 | 23 | /** 24 | * All integers will be decoded as BigInts. 25 | */ 26 | BIGINT = 'bigint', 27 | } 28 | 29 | export default IntDecoding; 30 | -------------------------------------------------------------------------------- /src/encoding/schema/index.ts: -------------------------------------------------------------------------------- 1 | export { BooleanSchema } from './boolean.js'; 2 | export { StringSchema } from './string.js'; 3 | export { Uint64Schema } from './uint64.js'; 4 | 5 | export { AddressSchema } from './address.js'; 6 | export { ByteArraySchema, FixedLengthByteArraySchema } from './bytearray.js'; 7 | 8 | export { BlockHashSchema } from './blockhash.js'; 9 | 10 | export { SpecialCaseBinaryStringSchema } from './binarystring.js'; 11 | 12 | export { ArraySchema } from './array.js'; 13 | export { 14 | NamedMapSchema, 15 | NamedMapEntry, 16 | allOmitEmpty, 17 | combineMaps, 18 | convertMap, 19 | Uint64MapSchema, 20 | StringMapSchema, 21 | ByteArrayMapSchema, 22 | SpecialCaseBinaryStringMapSchema, 23 | } from './map.js'; 24 | export { OptionalSchema } from './optional.js'; 25 | 26 | export { UntypedSchema } from './untyped.js'; 27 | -------------------------------------------------------------------------------- /src/client/v2/algod/block.ts: -------------------------------------------------------------------------------- 1 | import JSONRequest from '../jsonrequest.js'; 2 | import { HTTPClient, HTTPClientResponse } from '../../client.js'; 3 | import { decodeMsgpack } from '../../../encoding/encoding.js'; 4 | import { BlockResponse } from './models/types.js'; 5 | 6 | /** 7 | * block gets the block info for the given round. this call may block 8 | */ 9 | export default class Block extends JSONRequest { 10 | private round: bigint; 11 | 12 | constructor(c: HTTPClient, roundNumber: number | bigint) { 13 | super(c); 14 | this.round = BigInt(roundNumber); 15 | this.query = { format: 'msgpack' }; 16 | } 17 | 18 | path() { 19 | return `/v2/blocks/${this.round}`; 20 | } 21 | 22 | // eslint-disable-next-line class-methods-use-this 23 | prepare(response: HTTPClientResponse): BlockResponse { 24 | return decodeMsgpack(response.body, BlockResponse); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/client/v2/algod/getLedgerStateDeltaForTransactionGroup.ts: -------------------------------------------------------------------------------- 1 | import JSONRequest from '../jsonrequest.js'; 2 | import { HTTPClient, HTTPClientResponse } from '../../client.js'; 3 | import { decodeMsgpack } from '../../../encoding/encoding.js'; 4 | import { LedgerStateDelta } from '../../../types/statedelta.js'; 5 | 6 | export default class GetLedgerStateDeltaForTransactionGroup extends JSONRequest { 7 | constructor( 8 | c: HTTPClient, 9 | private id: string 10 | ) { 11 | super(c); 12 | this.query = { format: 'msgpack' }; 13 | } 14 | 15 | // eslint-disable-next-line class-methods-use-this 16 | path() { 17 | return `/v2/deltas/txn/group/${this.id}`; 18 | } 19 | 20 | // eslint-disable-next-line class-methods-use-this 21 | prepare(response: HTTPClientResponse): LedgerStateDelta { 22 | return decodeMsgpack(response.body, LedgerStateDelta); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/client/v2/algod/getLedgerStateDelta.ts: -------------------------------------------------------------------------------- 1 | import JSONRequest from '../jsonrequest.js'; 2 | import { HTTPClient, HTTPClientResponse } from '../../client.js'; 3 | import { decodeMsgpack } from '../../../encoding/encoding.js'; 4 | import { LedgerStateDelta } from '../../../types/statedelta.js'; 5 | 6 | export default class GetLedgerStateDelta extends JSONRequest { 7 | private round: bigint; 8 | 9 | constructor(c: HTTPClient, round: number | bigint) { 10 | super(c); 11 | this.round = BigInt(round); 12 | this.query = { format: 'msgpack' }; 13 | } 14 | 15 | // eslint-disable-next-line class-methods-use-this 16 | path() { 17 | return `/v2/deltas/${this.round}`; 18 | } 19 | 20 | // eslint-disable-next-line class-methods-use-this 21 | prepare(response: HTTPClientResponse): LedgerStateDelta { 22 | return decodeMsgpack(response.body, LedgerStateDelta); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Debug unit tests", 9 | "type": "node", 10 | "request": "launch", 11 | "program": "${workspaceRoot}/tests/mocha.js", 12 | "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/tsx", 13 | "console": "integratedTerminal", 14 | "internalConsoleOptions": "neverOpen", 15 | "env": { 16 | "NODE_ENV": "testing", 17 | "MOCHA_TIMEOUT": "0" 18 | }, 19 | "skipFiles": [ 20 | // Node.js internal core modules 21 | "/**", 22 | // Ignore all dependencies (optional) 23 | "${workspaceFolder}/node_modules/**" 24 | ] 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /src/client/v2/algod/setSyncRound.ts: -------------------------------------------------------------------------------- 1 | import JSONRequest from '../jsonrequest.js'; 2 | import { HTTPClient, HTTPClientResponse } from '../../client.js'; 3 | 4 | export default class SetSyncRound extends JSONRequest { 5 | private round: bigint; 6 | 7 | constructor(c: HTTPClient, round: number | bigint) { 8 | super(c); 9 | this.round = BigInt(round); 10 | } 11 | 12 | path() { 13 | return `/v2/ledger/sync/${this.round}`; 14 | } 15 | 16 | protected executeRequest( 17 | headers?: Record, 18 | customOptions?: Record 19 | ): Promise { 20 | return this.c.post({ 21 | relativePath: this.path(), 22 | data: null, 23 | requestHeaders: headers, 24 | customOptions, 25 | }); 26 | } 27 | 28 | // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars 29 | prepare(_response: HTTPClientResponse): void {} 30 | } 31 | -------------------------------------------------------------------------------- /src/client/v2/algod/setBlockOffsetTimestamp.ts: -------------------------------------------------------------------------------- 1 | import JSONRequest from '../jsonrequest.js'; 2 | import { HTTPClient, HTTPClientResponse } from '../../client.js'; 3 | 4 | export default class SetBlockOffsetTimestamp extends JSONRequest { 5 | private offset: bigint; 6 | 7 | constructor(c: HTTPClient, offset: number | bigint) { 8 | super(c); 9 | this.offset = BigInt(offset); 10 | } 11 | 12 | path() { 13 | return `/v2/devmode/blocks/offset/${this.offset}`; 14 | } 15 | 16 | protected executeRequest( 17 | headers?: Record, 18 | customOptions?: Record 19 | ): Promise { 20 | return this.c.post({ 21 | relativePath: this.path(), 22 | data: null, 23 | requestHeaders: headers, 24 | customOptions, 25 | }); 26 | } 27 | 28 | // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars 29 | prepare(_response: HTTPClientResponse): void {} 30 | } 31 | -------------------------------------------------------------------------------- /src/client/v2/indexer/makeHealthCheck.ts: -------------------------------------------------------------------------------- 1 | import JSONRequest from '../jsonrequest.js'; 2 | import { HTTPClientResponse } from '../../client.js'; 3 | import { decodeJSON } from '../../../encoding/encoding.js'; 4 | import { HealthCheck } from './models/types.js'; 5 | 6 | /** 7 | * Returns the health object for the service. 8 | * Returns 200 if healthy. 9 | * 10 | * #### Example 11 | * ```typescript 12 | * const health = await indexerClient.makeHealthCheck().do(); 13 | * ``` 14 | * 15 | * [Response data schema details](https://developer.algorand.org/docs/rest-apis/indexer/#get-health) 16 | * @category GET 17 | */ 18 | export default class MakeHealthCheck extends JSONRequest { 19 | /** 20 | * @returns `/health` 21 | */ 22 | // eslint-disable-next-line class-methods-use-this 23 | path() { 24 | return '/health'; 25 | } 26 | 27 | // eslint-disable-next-line class-methods-use-this 28 | prepare(response: HTTPClientResponse): HealthCheck { 29 | return decodeJSON(response.getJSONText(), HealthCheck); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /.github/workflows/pr-type-category.yml: -------------------------------------------------------------------------------- 1 | name: Check PR category and type 2 | on: 3 | pull_request: 4 | branches: 5 | - develop 6 | types: [opened, synchronize, reopened, labeled, unlabeled, edited] 7 | jobs: 8 | check_label: 9 | runs-on: ubuntu-latest 10 | name: Check PR Category and Type 11 | steps: 12 | - name: Checking for correct number of required github pr labels 13 | uses: mheap/github-action-required-labels@v2 14 | with: 15 | mode: exactly 16 | count: 1 17 | labels: "New Feature, Enhancement, Bug-Fix, Not-Yet-Enabled, Skip-Release-Notes" 18 | 19 | - name: "Checking for PR Category in PR title. Should be like ': '." 20 | env: 21 | PR_TITLE: ${{ github.event.pull_request.title }} 22 | run: | 23 | if [[ ! "$PR_TITLE" =~ ^.{2,}\:.{2,} ]]; then 24 | echo "## PR Category is missing from PR title. Please add it like ': '." >> GITHUB_STEP_SUMMARY 25 | exit 1 26 | fi 27 | -------------------------------------------------------------------------------- /src/client/v2/algod/accountAssetInformation.ts: -------------------------------------------------------------------------------- 1 | import JSONRequest from '../jsonrequest.js'; 2 | import { HTTPClient, HTTPClientResponse } from '../../client.js'; 3 | import { decodeJSON } from '../../../encoding/encoding.js'; 4 | import { AccountAssetResponse } from './models/types.js'; 5 | import { Address } from '../../../encoding/address.js'; 6 | 7 | export default class AccountAssetInformation extends JSONRequest { 8 | private account: string; 9 | private assetID: bigint; 10 | 11 | constructor( 12 | c: HTTPClient, 13 | account: string | Address, 14 | assetID: number | bigint 15 | ) { 16 | super(c); 17 | this.account = account.toString(); 18 | this.assetID = BigInt(assetID); 19 | } 20 | 21 | path() { 22 | return `/v2/accounts/${this.account}/assets/${this.assetID}`; 23 | } 24 | 25 | // eslint-disable-next-line class-methods-use-this 26 | prepare(response: HTTPClientResponse): AccountAssetResponse { 27 | return decodeJSON(response.getJSONText(), AccountAssetResponse); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/client/v2/algod/pendingTransactions.ts: -------------------------------------------------------------------------------- 1 | import JSONRequest from '../jsonrequest.js'; 2 | import { HTTPClient, HTTPClientResponse } from '../../client.js'; 3 | import { decodeMsgpack } from '../../../encoding/encoding.js'; 4 | import { PendingTransactionsResponse } from './models/types.js'; 5 | 6 | /** 7 | * pendingTransactionsInformation returns transactions that are pending in the pool 8 | */ 9 | export default class PendingTransactions extends JSONRequest { 10 | constructor(c: HTTPClient) { 11 | super(c); 12 | this.query.format = 'msgpack'; 13 | } 14 | 15 | /* eslint-disable class-methods-use-this */ 16 | path() { 17 | return '/v2/transactions/pending'; 18 | } 19 | 20 | prepare(response: HTTPClientResponse): PendingTransactionsResponse { 21 | return decodeMsgpack(response.body, PendingTransactionsResponse); 22 | } 23 | /* eslint-enable class-methods-use-this */ 24 | 25 | // max sets the maximum number of txs to return 26 | max(max: number) { 27 | this.query.max = max; 28 | return this; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/abi/interface.ts: -------------------------------------------------------------------------------- 1 | import { ABIMethod, ABIMethodParams, getMethodByName } from './method.js'; 2 | 3 | export interface ABIInterfaceParams { 4 | name: string; 5 | desc?: string; 6 | methods: ABIMethodParams[]; 7 | } 8 | 9 | export class ABIInterface { 10 | public readonly name: string; 11 | public readonly description?: string; 12 | public readonly methods: ABIMethod[]; 13 | 14 | constructor(params: ABIInterfaceParams) { 15 | if (typeof params.name !== 'string' || !Array.isArray(params.methods)) { 16 | throw new Error('Invalid ABIInterface parameters'); 17 | } 18 | 19 | this.name = params.name; 20 | this.description = params.desc; 21 | this.methods = params.methods.map((method) => new ABIMethod(method)); 22 | } 23 | 24 | toJSON(): ABIInterfaceParams { 25 | return { 26 | name: this.name, 27 | desc: this.description, 28 | methods: this.methods.map((method) => method.toJSON()), 29 | }; 30 | } 31 | 32 | getMethodByName(name: string): ABIMethod { 33 | return getMethodByName(this.methods, name); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/client/v2/algod/pendingTransactionInformation.ts: -------------------------------------------------------------------------------- 1 | import JSONRequest from '../jsonrequest.js'; 2 | import { HTTPClient, HTTPClientResponse } from '../../client.js'; 3 | import { decodeMsgpack } from '../../../encoding/encoding.js'; 4 | import { PendingTransactionResponse } from './models/types.js'; 5 | 6 | /** 7 | * returns the transaction information for a specific txid of a pending transaction 8 | */ 9 | export default class PendingTransactionInformation extends JSONRequest { 10 | constructor( 11 | c: HTTPClient, 12 | private txid: string 13 | ) { 14 | super(c); 15 | this.query.format = 'msgpack'; 16 | } 17 | 18 | // eslint-disable-next-line class-methods-use-this 19 | prepare(response: HTTPClientResponse): PendingTransactionResponse { 20 | return decodeMsgpack(response.body, PendingTransactionResponse); 21 | } 22 | 23 | path() { 24 | return `/v2/transactions/pending/${this.txid}`; 25 | } 26 | 27 | // max sets the maximum number of txs to return 28 | max(max: number) { 29 | this.query.max = max; 30 | return this; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/client/v2/algod/accountApplicationInformation.ts: -------------------------------------------------------------------------------- 1 | import JSONRequest from '../jsonrequest.js'; 2 | import { HTTPClient, HTTPClientResponse } from '../../client.js'; 3 | import { decodeJSON } from '../../../encoding/encoding.js'; 4 | import { AccountApplicationResponse } from './models/types.js'; 5 | import { Address } from '../../../encoding/address.js'; 6 | 7 | export default class AccountApplicationInformation extends JSONRequest { 8 | private account: string; 9 | private applicationID: bigint; 10 | 11 | constructor( 12 | c: HTTPClient, 13 | account: string | Address, 14 | applicationID: number | bigint 15 | ) { 16 | super(c); 17 | this.account = account.toString(); 18 | this.applicationID = BigInt(applicationID); 19 | } 20 | 21 | path() { 22 | return `/v2/accounts/${this.account}/applications/${this.applicationID}`; 23 | } 24 | 25 | // eslint-disable-next-line class-methods-use-this 26 | prepare(response: HTTPClientResponse): AccountApplicationResponse { 27 | return decodeJSON(response.getJSONText(), AccountApplicationResponse); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/client/v2/algod/getTransactionGroupLedgerStateDeltasForRound.ts: -------------------------------------------------------------------------------- 1 | import JSONRequest from '../jsonrequest.js'; 2 | import { TransactionGroupLedgerStateDeltasForRoundResponse } from './models/types.js'; 3 | import { HTTPClient, HTTPClientResponse } from '../../client.js'; 4 | import { decodeMsgpack } from '../../../encoding/encoding.js'; 5 | 6 | export default class GetTransactionGroupLedgerStateDeltasForRound extends JSONRequest { 7 | private round: bigint; 8 | 9 | constructor(c: HTTPClient, round: number | bigint) { 10 | super(c); 11 | this.round = BigInt(round); 12 | this.query = { format: 'msgpack' }; 13 | } 14 | 15 | // eslint-disable-next-line class-methods-use-this 16 | path() { 17 | return `/v2/deltas/${this.round}/txn/group`; 18 | } 19 | 20 | // eslint-disable-next-line class-methods-use-this 21 | prepare( 22 | response: HTTPClientResponse 23 | ): TransactionGroupLedgerStateDeltasForRoundResponse { 24 | return decodeMsgpack( 25 | response.body, 26 | TransactionGroupLedgerStateDeltasForRoundResponse 27 | ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Algorand, llc 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /tests/cucumber/unit.tags: -------------------------------------------------------------------------------- 1 | @unit.abijson 2 | @unit.abijson.byname 3 | @unit.algod 4 | @unit.algod.ledger_refactoring 5 | @unit.algod.heartbeat 6 | @unit.algod.heartbeat.msgp 7 | @unit.applications 8 | @unit.applications.boxes 9 | @unit.atomic_transaction_composer 10 | @unit.blocksummary 11 | @unit.blocktxids 12 | @unit.dryrun 13 | @unit.dryrun.trace.application 14 | @unit.feetest 15 | @unit.indexer 16 | @unit.indexer.blockheaders 17 | @unit.indexer.ledger_refactoring 18 | @unit.indexer.logs 19 | @unit.indexer.heartbeat 20 | @unit.offline 21 | @unit.program_sanity_check 22 | @unit.ready 23 | @unit.rekey 24 | @unit.responses 25 | @unit.responses.231 26 | @unit.responses.participationupdates 27 | @unit.responses.unlimited_assets 28 | @unit.responses.blocksummary 29 | @unit.responses.minbalance 30 | @unit.responses.statedelta 31 | @unit.responses.sync 32 | @unit.responses.timestamp 33 | @unit.responses.txid.json 34 | @unit.responses.txngroupdeltas 35 | @unit.sourcemapv2 36 | @unit.stateproof.paths 37 | @unit.stateproof.responses 38 | @unit.sync 39 | @unit.tealsign 40 | @unit.timestamp 41 | @unit.transactions 42 | @unit.transactions.keyreg 43 | @unit.transactions.payment 44 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | mode: 'production', 5 | entry: './src/index.ts', 6 | output: { 7 | filename: 'algosdk.min.js', 8 | path: path.resolve(__dirname, 'dist/browser'), 9 | library: { 10 | type: 'umd', 11 | name: 'algosdk', 12 | }, 13 | }, 14 | devtool: 'source-map', 15 | resolve: { 16 | // Add '.ts' as resolvable extensions 17 | extensions: ['.ts', '.js'], 18 | extensionAlias: { '.js': ['.ts', '.js'] }, 19 | }, 20 | module: { 21 | rules: [ 22 | // All files with a '.ts' extension will be handled by 'ts-loader'. 23 | { 24 | test: /\.ts$/, 25 | loader: 'ts-loader', 26 | options: { 27 | configFile: path.resolve(__dirname, 'tsconfig-browser.json'), 28 | }, 29 | }, 30 | 31 | // All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'. 32 | { test: /\.js$/, loader: 'source-map-loader' }, 33 | ], 34 | // Don't parse tweetnacl module — https://github.com/dchest/tweetnacl-js/wiki/Using-with-Webpack 35 | noParse: [/[\\/]tweetnacl[\\/]/, /[\\/]tweetnacl-auth[\\/]/], 36 | }, 37 | }; 38 | -------------------------------------------------------------------------------- /src/client/v2/algod/pendingTransactionsByAddress.ts: -------------------------------------------------------------------------------- 1 | import JSONRequest from '../jsonrequest.js'; 2 | import { HTTPClient, HTTPClientResponse } from '../../client.js'; 3 | import { decodeMsgpack } from '../../../encoding/encoding.js'; 4 | import { PendingTransactionsResponse } from './models/types.js'; 5 | import { Address } from '../../../encoding/address.js'; 6 | 7 | /** 8 | * returns all transactions for a PK [addr] in the [first, last] rounds range. 9 | */ 10 | export default class PendingTransactionsByAddress extends JSONRequest { 11 | private address: string; 12 | 13 | constructor(c: HTTPClient, address: string | Address) { 14 | super(c); 15 | this.address = address.toString(); 16 | this.query.format = 'msgpack'; 17 | } 18 | 19 | // eslint-disable-next-line class-methods-use-this 20 | prepare(response: HTTPClientResponse): PendingTransactionsResponse { 21 | return decodeMsgpack(response.body, PendingTransactionsResponse); 22 | } 23 | 24 | path() { 25 | return `/v2/accounts/${this.address}/transactions/pending`; 26 | } 27 | 28 | // max sets the maximum number of txs to return 29 | max(max: number) { 30 | this.query.max = max; 31 | return this; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/encoding/bigint.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * bigIntToBytes converts a BigInt to a big-endian Uint8Array for encoding. 3 | * @param bi - The bigint to convert. 4 | * @param size - The size of the resulting byte array. 5 | * @returns A byte array containing the big-endian encoding of the input bigint 6 | */ 7 | export function bigIntToBytes(bi: bigint | number, size: number) { 8 | let hex = bi.toString(16); 9 | // Pad the hex with zeros so it matches the size in bytes 10 | if (hex.length !== size * 2) { 11 | hex = hex.padStart(size * 2, '0'); 12 | } 13 | const byteArray = new Uint8Array(hex.length / 2); 14 | for (let i = 0, j = 0; i < hex.length / 2; i++, j += 2) { 15 | byteArray[i] = parseInt(hex.slice(j, j + 2), 16); 16 | } 17 | return byteArray; 18 | } 19 | 20 | /** 21 | * bytesToBigInt produces a bigint from a binary representation. 22 | * 23 | * @param bytes - The Uint8Array to convert. 24 | * @returns The bigint that was encoded in the input data. 25 | */ 26 | export function bytesToBigInt(bytes: Uint8Array) { 27 | let res = BigInt(0); 28 | const buf = new DataView(bytes.buffer, bytes.byteOffset); 29 | for (let i = 0; i < bytes.length; i++) { 30 | res = BigInt(Number(buf.getUint8(i))) + res * BigInt(256); 31 | } 32 | return res; 33 | } 34 | -------------------------------------------------------------------------------- /FAQ.md: -------------------------------------------------------------------------------- 1 | # Frequently Asked Questions 2 | 3 | ## Where did the `dist` folder go? 4 | 5 | Starting with version 1.9.0, a minified browser bundle can be obtained from npm CDNs such as [unpkg](https://unpkg.com/) or [jsDelivr](https://www.jsdelivr.com/). The link can be found in the [README.md](README.md). 6 | 7 | In prior versions, the browser bundles were made available in the `dist` directory. In order to access those, look in the `dist` folder on the version's GitHub tag, e.g. https://github.com/algorand/js-algorand-sdk/tree/v1.8.1/dist. 8 | 9 | ## Can I host the browser bundle myself? 10 | 11 | Yes! If you would instead prefer to host the package yourself, a minified browser bundle can be found in the `dist/browser/` folder of the published npm package starting with version 1.9.0. 12 | 13 | ## How do I generate the SRI hash of `algosdk.min.js`? 14 | 15 | The SRI hash of `algosdk.min.js` is the base64 string after `sha384-` in the `integrity` attribute of the `