Repository: algorand/js-algorand-sdk
Pull request #717 (2022-12-15 20:14:12)

v2: Make breaking changes from v1 to v2.0.0 
Prepares for a v2.0.0 release by batching breaking changes described in https://github.com/algorand/js-algorand-sdk/issues/650.


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1556f10..71dd3a9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,19 @@
+# 2.0.0
+
+## What's Changed
+
+### Breaking changes
+
+- Remove v1 algod API (`client.algod`) due to API end-of-life (2022-12-01). Instead, use v2 algod API (`client.v2.algod.algod`).
+- Remove `cost` field in `DryrunTxnResult` in favor of 2 fields: `budget-added` and `budget-consumed`. `cost` can be derived by `budget-consumed - budget-added`.
+- Remove logicsig templates (`logicTemplates`), `logic/langspec.json`, `logic.logic` depending on `langspec.json`.
+- Regenerate algod models so every constructor requires an object to be passed in. Previously, only constructors with more than 4 argument specified this.
+- Remove unused generated types: `CatchpointAbortResponse`, `CatchpointStartResponse`.
+- Remove following methods in favor of the methods with `WithSuggestedParams` suffix:
+  - `makePaymentTxn`, `makeKeyRegistrationTxn`, `makeAssetCreateTxn`, `makeAssetConfigTxn`, `makeAssetDestroyTxn`, `makeAssetFreezeTxn`, `makeAssetTransferTxn`.
+- Remove `makeLogicSig` in favor of either using `LogicSigAccount` (preferred) or directly invoking `LogicSig` constructor.
+- Remove `EncodedMultisigBlob` in favor of `EncodedSignedTransaction.
+
 # v1.24.1
 
 ## What's Changed
diff --git a/examples/logic_sig_example.js b/examples/logic_sig_example.js
index 90ecaef..36b1370 100644
--- a/examples/logic_sig_example.js
+++ b/examples/logic_sig_example.js
@@ -24,7 +24,7 @@ async function main() {
   );
 
   // create a logic signature
-  const lsig = algosdk.makeLogicSig(programBytes);
+  const lsig = new algosdk.LogicSigAccount(programBytes);
   const sender = lsig.address();
 
   // retrieve a receiver
diff --git a/src/client/algod.js b/src/client/algod.js
deleted file mode 100644
index 284870f..0000000
--- a/src/client/algod.js
+++ /dev/null
@@ -1,365 +0,0 @@
-const { default: HTTPClient } = require('./client');
-const { setSendTransactionHeaders } = require('./v2/algod/sendRawTransaction');
-
-/** @deprecated v1 algod APIs are deprecated, please use the v2 client */
-function Algod(
-  token = '',
-  baseServer = 'http://r2.algorand.network',
-  port = 4180,
-  headers = {}
-) {
-  // workaround to allow backwards compatibility for multiple headers
-  let tokenHeader = token;
-  if (typeof tokenHeader === 'string') {
-    tokenHeader = { 'X-Algo-API-Token': tokenHeader };
-  }
-
-  // Get client
-  const c = new HTTPClient(tokenHeader, baseServer, port, headers);
-
-  /**
-   * Takes an object and convert its note field to Buffer, if exist.
-   * @param o
-   * @returns {*}
-   * @deprecated v1 algod APIs are deprecated, please use the v2 client
-   */
-  function noteb64ToNote(o) {
-    if (!(o.noteb64 === undefined || o.noteb64 === null)) {
-      // eslint-disable-next-line no-param-reassign
-      o.note = Buffer.from(o.noteb64, 'base64');
-    }
-    return o;
-  }
-
-  /**
-   * status retrieves the StatusResponse from the running node
-   * @param headerObj, optional
-   * @returns {Promise<*>}
-   * @deprecated v1 algod APIs are deprecated, please use the v2 client
-   */
-  this.status = async (headerObj = {}) => {
-    const res = await c.get('/v1/status', {}, headerObj);
-    return res.body;
-  };
-
-  /**
-   * healthCheck returns an empty object iff the node is running
-   * @param headerObj, optional
-   * @returns {Promise<*>}
-   * @deprecated v1 algod APIs are deprecated, please use the v2 client
-   */
-  this.healthCheck = async (headerObj = {}) => {
-    const res = await c.get('/health', {}, headerObj);
-    if (!res.ok) {
-      throw new Error(`Health response: ${res.status}`);
-    }
-    return {};
-  };
-
-  /**
-   * statusAfterBlock waits for round roundNumber to occur then returns the StatusResponse for this round.
-   * This call blocks
-   * @param roundNumber
-   * @param headerObj, optional
-   * @returns {Promise<*>}
-   * @deprecated v1 algod APIs are deprecated, please use the v2 client
-   */
-  this.statusAfterBlock = async (roundNumber, headerObj = {}) => {
-    if (!Number.isInteger(roundNumber))
-      throw Error('roundNumber should be an integer');
-    const res = await c.get(
-      `/v1/status/wait-for-block-after/${roundNumber}`,
-      {},
-      headerObj
-    );
-    return res.body;
-  };
-
-  /**
-   * pendingTransactions asks algod for a snapshot of current pending txns on the node, bounded by maxTxns.
-   * If maxTxns = 0, fetches as many transactions as possible.
-   * @param maxTxns - number
-   * @param headerObj, optional
-   * @returns {Promise<*>}
-   * @deprecated v1 algod APIs are deprecated, please use the v2 client
-   */
-  this.pendingTransactions = async (maxTxns, headerObj = {}) => {
-    if (!Number.isInteger(maxTxns)) throw Error('maxTxns should be an integer');
-    const res = await c.get(
-      '/v1/transactions/pending',
-      { max: maxTxns },
-      headerObj
-    );
-    if (
-      res.statusCode === 200 &&
-      res.body.truncatedTxns.transactions !== undefined
-    ) {
-      for (let i = 0; i < res.body.truncatedTxns.transactions.length; i++) {
-        res.body.truncatedTxns.transactions[i] = noteb64ToNote(
-          res.body.truncatedTxns.transactions[i]
-        );
-      }
-    }
-    return res.body;
-  };
-
-  /**
-   * versions retrieves the VersionResponse from the running node
-   * @param headerObj, optional
-   * @returns {Promise<*>}
-   * @deprecated v1 algod APIs are deprecated, please use the v2 client
-   */
-  this.versions = async (headerObj = {}) => {
-    const res = await c.get('/versions', {}, headerObj);
-    return res.body;
-  };
-
-  /**
-   * LedgerSupply gets the supply details for the specified node's Ledger
-   * @param headerObj, optional
-   * @returns {Promise<*>}
-   * @deprecated v1 algod APIs are deprecated, please use the v2 client
-   */
-  this.ledgerSupply = async (headerObj = {}) => {
-    const res = await c.get('/v1/ledger/supply', {}, headerObj);
-    return res.body;
-  };
-
-  /**
-   * transactionsByAddress returns all transactions for a PK [addr] in the [first, last] rounds range.
-   * @param addr - string
-   * @param first - number, optional
-   * @param last - number, optional
-   * @param maxTxns - number, optional
-   * @param headers, optional
-   * @returns {Promise<*>}
-   * @deprecated v1 algod APIs are deprecated, please use the v2 client
-   */
-  this.transactionByAddress = async (
-    addr,
-    first = null,
-    last = null,
-    maxTxns = null,
-    headerObj = {}
-  ) => {
-    if (first !== null && !Number.isInteger(first)) {
-      throw Error('first round should be an integer');
-    }
-    if (last !== null && !Number.isInteger(last)) {
-      throw Error('last round should be an integer');
-    }
-    const res = await c.get(
-      `/v1/account/${addr}/transactions`,
-      { firstRound: first, lastRound: last, max: maxTxns },
-      headerObj
-    );
-    if (res.statusCode === 200 && res.body.transactions !== undefined) {
-      for (let i = 0; i < res.body.transactions.length; i++) {
-        res.body.transactions[i] = noteb64ToNote(res.body.transactions[i]);
-      }
-    }
-    return res.body;
-  };
-
-  /**
-   * transactionsByAddressAndDate returns all transactions for a PK [addr] in the [fromDate, toDate] date range.
-   * The date is a string in the YYYY-MM-DD format.
-   * @param addr - string
-   * @param fromDate - string
-   * @param toDate - string
-   * @param maxTxns - number, optional
-   * @param headerObj, optional
-   * @returns {Promise<*>}
-   * @deprecated v1 algod APIs are deprecated, please use the v2 client
-   */
-  this.transactionByAddressAndDate = async (
-    addr,
-    fromDate,
-    toDate,
-    maxTxns = null,
-    headerObj = {}
-  ) => {
-    const res = await c.get(
-      `/v1/account/${addr}/transactions`,
-      { fromDate, toDate, max: maxTxns },
-      headerObj
-    );
-    if (res.statusCode === 200 && res.body.transactions !== undefined) {
-      for (let i = 0; i < res.body.transactions.length; i++) {
-        res.body.transactions[i] = noteb64ToNote(res.body.transactions[i]);
-      }
-    }
-    return res.body;
-  };
-
-  /**
-   * transactionById returns the a transaction information of a specific txid [txId]
-   * Note - This method is allowed only when Indexer is enabled.
-   * @param txid
-   * @param headerObj, optional
-   * @returns {Promise<*>}
-   * @deprecated v1 algod APIs are deprecated, please use the v2 client
-   */
-  this.transactionById = async (txid, headerObj = {}) => {
-    const res = await c.get(`/v1/transaction/${txid}`, {}, headerObj);
-    if (res.statusCode === 200) {
-      res.body = noteb64ToNote(res.body);
-    }
-    return res.body;
-  };
-
-  /**
-   * transactionInformation returns the transaction information of a specific txid and an address
-   * @param addr
-   * @param txid
-   * @param headerObj, optional
-   * @returns {Promise<*>}
-   * @deprecated v1 algod APIs are deprecated, please use the v2 client
-   */
-  this.transactionInformation = async (addr, txid, headerObj = {}) => {
-    const res = await c.get(
-      `/v1/account/${addr}/transaction/${txid}`,
-      {},
-      headerObj
-    );
-    if (res.statusCode === 200) {
-      res.body = noteb64ToNote(res.body);
-    }
-    return res.body;
-  };
-
-  /**
-   * pendingTransactionInformation returns the transaction information for a specific txid of a pending transaction
-   * @param txid
-   * @param headerObj, optional
-   * @returns {Promise<*>}
-   * @deprecated v1 algod APIs are deprecated, please use the v2 client
-   */
-  this.pendingTransactionInformation = async (txid, headerObj = {}) => {
-    const res = await c.get(`/v1/transactions/pending/${txid}`, {}, headerObj);
-    if (res.statusCode === 200) {
-      res.body = noteb64ToNote(res.body);
-    }
-    return res.body;
-  };
-
-  /**
-   * accountInformation returns the passed account's information
-   * @param addr - string
-   * @param headerObj, optional
-   * @returns {Promise<*>}
-   * @deprecated v1 algod APIs are deprecated, please use the v2 client
-   */
-  this.accountInformation = async (addr, headerObj = {}) => {
-    const res = await c.get(`/v1/account/${addr}`, {}, headerObj);
-    return res.body;
-  };
-
-  /**
-   * assetInformation returns the information for the asset with the passed creator and index
-   * @param index - number
-   * @param headerObj, optional
-   * @returns {Promise<*>}
-   * @deprecated v1 algod APIs are deprecated, please use the v2 client
-   */
-  this.assetInformation = async (index, headerObj = {}) => {
-    const res = await c.get(`/v1/asset/${index}`, {}, headerObj);
-    return res.body;
-  };
-
-  /**
-   * suggestedFee gets the recommended transaction fee from the node
-   * @param headerObj, optional
-   * @returns {Promise<*>}
-   * @deprecated v1 algod APIs are deprecated, please use the v2 client
-   */
-  this.suggestedFee = async (headerObj = {}) => {
-    const res = await c.get('/v1/transactions/fee', {}, headerObj);
-    return res.body;
-  };
-
-  /**
-   * sendRawTransaction gets an encoded SignedTxn and broadcasts it to the network
-   * @param txn - Uin8Array
-   * @param headerObj, optional
-   * @returns {Promise<*>}
-   * @deprecated v1 algod APIs are deprecated, please use the v2 client
-   */
-  this.sendRawTransaction = async (txn, headerObj = {}) => {
-    const txHeaders = setSendTransactionHeaders(headerObj);
-    const res = await c.post('/v1/transactions', Buffer.from(txn), txHeaders);
-    return res.body;
-  };
-
-  /**
-   * sendRawTransactions gets a list of encoded SignedTxns and broadcasts it to the network
-   * @param txn - Array of Uin8Array
-   * @param headerObj, optional
-   * @returns {Promise<*>}
-   * @deprecated v1 algod APIs are deprecated, please use the v2 client
-   */
-  this.sendRawTransactions = async (txns, headerObj = {}) => {
-    const txHeaders = setSendTransactionHeaders(headerObj);
-    const merged = Array.prototype.concat(
-      ...txns.map((arr) => Array.from(arr))
-    );
-    const res = await c.post(
-      '/v1/transactions',
-      Buffer.from(merged),
-      txHeaders
-    );
-    return res.body;
-  };
-
-  /**
-   * getTransactionParams returns to common needed parameters for a new transaction
-   * @param headerObj, optional
-   * @returns {Promise<*>}
-   * @deprecated v1 algod APIs are deprecated, please use the v2 client
-   */
-  this.getTransactionParams = async (headerObj = {}) => {
-    const res = await c.get('/v1/transactions/params', {}, headerObj);
-    return res.body;
-  };
-
-  /**
-   * suggestParams returns to common needed parameters for a new transaction, in a format the transaction builder expects
-   * @param headerObj, optional
-   * @returns {Object}
-   * @deprecated v1 algod APIs are deprecated, please use the v2 client
-   */
-  this.suggestParams = async (headerObj = {}) => {
-    const result = await this.getTransactionParams(headerObj);
-    return {
-      flatFee: false,
-      fee: result.fee,
-      firstRound: result.lastRound,
-      lastRound: result.lastRound + 1000,
-      genesisID: result.genesisID,
-      genesisHash: result.genesishashb64,
-    };
-  };
-
-  /**
-   * block gets the block info for the given round This call blocks
-   * @param roundNumber
-   * @param headerObj, optional
-   * @returns {Promise<*>}
-   * @deprecated v1 algod APIs are deprecated, please use the v2 client
-   */
-  this.block = async (roundNumber, headerObj = {}) => {
-    if (!Number.isInteger(roundNumber))
-      throw Error('roundNumber should be an integer');
-    const res = await c.get(`/v1/block/${roundNumber}`, {}, headerObj);
-    if (res.statusCode === 200 && res.body.txns.transactions !== undefined) {
-      for (let i = 0; i < res.body.txns.transactions.length; i++) {
-        res.body.txns.transactions[i] = noteb64ToNote(
-          res.body.txns.transactions[i]
-        );
-      }
-    }
-    return res.body;
-  };
-}
-
-module.exports = { Algod };
diff --git a/src/client/v2/algod/algod.ts b/src/client/v2/algod/algod.ts
index 237ae23..ce19602 100644
--- a/src/client/v2/algod/algod.ts
+++ b/src/client/v2/algod/algod.ts
@@ -69,8 +69,8 @@ export default class AlgodClient extends ServiceClient {
       | AlgodTokenHeader
       | CustomTokenHeader
       | BaseHTTPClient,
-    baseServer = 'http://r2.algorand.network',
-    port: string | number = 4180,
+    baseServer: string,
+    port?: string | number,
     headers: Record<string, string> = {}
   ) {
     super('X-Algo-API-Token', tokenOrBaseClient, baseServer, port, headers);
diff --git a/src/client/v2/algod/models/types.ts b/src/client/v2/algod/models/types.ts
index 98fbe15..a8f6303 100644
--- a/src/client/v2/algod/models/types.ts
+++ b/src/client/v2/algod/models/types.ts
@@ -440,11 +440,15 @@ export class AccountApplicationResponse extends BaseModel {
    * global data.
    * The raw account uses `AppParams` for this type.
    */
-  constructor(
-    round: number | bigint,
-    appLocalState?: ApplicationLocalState,
-    createdApp?: ApplicationParams
-  ) {
+  constructor({
+    round,
+    appLocalState,
+    createdApp,
+  }: {
+    round: number | bigint;
+    appLocalState?: ApplicationLocalState;
+    createdApp?: ApplicationParams;
+  }) {
     super();
     this.round = round;
     this.appLocalState = appLocalState;
@@ -464,15 +468,17 @@ export class AccountApplicationResponse extends BaseModel {
     /* eslint-disable dot-notation */
     if (typeof data['round'] === 'undefined')
       throw new Error(`Response is missing required field 'round': ${data}`);
-    return new AccountApplicationResponse(
-      data['round'],
-      typeof data['app-local-state'] !== 'undefined'
-        ? ApplicationLocalState.from_obj_for_encoding(data['app-local-state'])
-        : undefined,
-      typeof data['created-app'] !== 'undefined'
-        ? ApplicationParams.from_obj_for_encoding(data['created-app'])
-        : undefined
-    );
+    return new AccountApplicationResponse({
+      round: data['round'],
+      appLocalState:
+        typeof data['app-local-state'] !== 'undefined'
+          ? ApplicationLocalState.from_obj_for_encoding(data['app-local-state'])
+          : undefined,
+      createdApp:
+        typeof data['created-app'] !== 'undefined'
+          ? ApplicationParams.from_obj_for_encoding(data['created-app'])
+          : undefined,
+    });
     /* eslint-enable dot-notation */
   }
 }
@@ -508,11 +514,15 @@ export class AccountAssetResponse extends BaseModel {
    * @param createdAsset - (apar) parameters of the asset created by this account.
    * The raw account uses `AssetParams` for this type.
    */
-  constructor(
-    round: number | bigint,
-    assetHolding?: AssetHolding,
-    createdAsset?: AssetParams
-  ) {
+  constructor({
+    round,
+    assetHolding,
+    createdAsset,
+  }: {
+    round: number | bigint;
+    assetHolding?: AssetHolding;
+    createdAsset?: AssetParams;
+  }) {
     super();
     this.round = round;
     this.assetHolding = assetHolding;
@@ -532,15 +542,17 @@ export class AccountAssetResponse extends BaseModel {
     /* eslint-disable dot-notation */
     if (typeof data['round'] === 'undefined')
       throw new Error(`Response is missing required field 'round': ${data}`);
-    return new AccountAssetResponse(
-      data['round'],
-      typeof data['asset-holding'] !== 'undefined'
-        ? AssetHolding.from_obj_for_encoding(data['asset-holding'])
-        : undefined,
-      typeof data['created-asset'] !== 'undefined'
-        ? AssetParams.from_obj_for_encoding(data['created-asset'])
-        : undefined
-    );
+    return new AccountAssetResponse({
+      round: data['round'],
+      assetHolding:
+        typeof data['asset-holding'] !== 'undefined'
+          ? AssetHolding.from_obj_for_encoding(data['asset-holding'])
+          : undefined,
+      createdAsset:
+        typeof data['created-asset'] !== 'undefined'
+          ? AssetParams.from_obj_for_encoding(data['created-asset'])
+          : undefined,
+    });
     /* eslint-enable dot-notation */
   }
 }
@@ -686,7 +698,13 @@ export class AccountStateDelta extends BaseModel {
    * @param address -
    * @param delta - Application state delta.
    */
-  constructor(address: string, delta: EvalDeltaKeyValue[]) {
+  constructor({
+    address,
+    delta,
+  }: {
+    address: string;
+    delta: EvalDeltaKeyValue[];
+  }) {
     super();
     this.address = address;
     this.delta = delta;
@@ -706,10 +724,10 @@ export class AccountStateDelta extends BaseModel {
       throw new Error(
         `Response is missing required array field 'delta': ${data}`
       );
-    return new AccountStateDelta(
-      data['address'],
-      data['delta'].map(EvalDeltaKeyValue.from_obj_for_encoding)
-    );
+    return new AccountStateDelta({
+      address: data['address'],
+      delta: data['delta'].map(EvalDeltaKeyValue.from_obj_for_encoding),
+    });
     /* eslint-enable dot-notation */
   }
 }
@@ -733,7 +751,13 @@ export class Application extends BaseModel {
    * @param id - (appidx) application index.
    * @param params - (appparams) application parameters.
    */
-  constructor(id: number | bigint, params: ApplicationParams) {
+  constructor({
+    id,
+    params,
+  }: {
+    id: number | bigint;
+    params: ApplicationParams;
+  }) {
     super();
     this.id = id;
     this.params = params;
@@ -751,10 +775,10 @@ export class Application extends BaseModel {
       throw new Error(`Response is missing required field 'id': ${data}`);
     if (typeof data['params'] === 'undefined')
       throw new Error(`Response is missing required field 'params': ${data}`);
-    return new Application(
-      data['id'],
-      ApplicationParams.from_obj_for_encoding(data['params'])
-    );
+    return new Application({
+      id: data['id'],
+      params: ApplicationParams.from_obj_for_encoding(data['params']),
+    });
     /* eslint-enable dot-notation */
   }
 }
@@ -784,11 +808,15 @@ export class ApplicationLocalState extends BaseModel {
    * @param schema - (hsch) schema.
    * @param keyValue - (tkv) storage.
    */
-  constructor(
-    id: number | bigint,
-    schema: ApplicationStateSchema,
-    keyValue?: TealKeyValue[]
-  ) {
+  constructor({
+    id,
+    schema,
+    keyValue,
+  }: {
+    id: number | bigint;
+    schema: ApplicationStateSchema;
+    keyValue?: TealKeyValue[];
+  }) {
     super();
     this.id = id;
     this.schema = schema;
@@ -810,13 +838,14 @@ export class ApplicationLocalState extends BaseModel {
       throw new Error(`Response is missing required field 'id': ${data}`);
     if (typeof data['schema'] === 'undefined')
       throw new Error(`Response is missing required field 'schema': ${data}`);
-    return new ApplicationLocalState(
-      data['id'],
-      ApplicationStateSchema.from_obj_for_encoding(data['schema']),
-      typeof data['key-value'] !== 'undefined'
-        ? data['key-value'].map(TealKeyValue.from_obj_for_encoding)
-        : undefined
-    );
+    return new ApplicationLocalState({
+      id: data['id'],
+      schema: ApplicationStateSchema.from_obj_for_encoding(data['schema']),
+      keyValue:
+        typeof data['key-value'] !== 'undefined'
+          ? data['key-value'].map(TealKeyValue.from_obj_for_encoding)
+          : undefined,
+    });
     /* eslint-enable dot-notation */
   }
 }
@@ -973,7 +1002,13 @@ export class ApplicationStateSchema extends BaseModel {
    * @param numUint - (nui) num of uints.
    * @param numByteSlice - (nbs) num of byte slices.
    */
-  constructor(numUint: number | bigint, numByteSlice: number | bigint) {
+  constructor({
+    numUint,
+    numByteSlice,
+  }: {
+    numUint: number | bigint;
+    numByteSlice: number | bigint;
+  }) {
     super();
     this.numUint = numUint;
     this.numByteSlice = numByteSlice;
@@ -995,7 +1030,10 @@ export class ApplicationStateSchema extends BaseModel {
       throw new Error(
         `Response is missing required field 'num-byte-slice': ${data}`
       );
-    return new ApplicationStateSchema(data['num-uint'], data['num-byte-slice']);
+    return new ApplicationStateSchema({
+      numUint: data['num-uint'],
+      numByteSlice: data['num-byte-slice'],
+    });
     /* eslint-enable dot-notation */
   }
 }
@@ -1025,7 +1063,13 @@ export class Asset extends BaseModel {
    * Definition:
    * data/transactions/asset.go : AssetParams
    */
-  constructor(index: number | bigint, params: AssetParams) {
+  constructor({
+    index,
+    params,
+  }: {
+    index: number | bigint;
+    params: AssetParams;
+  }) {
     super();
     this.index = index;
     this.params = params;
@@ -1043,10 +1087,10 @@ export class Asset extends BaseModel {
       throw new Error(`Response is missing required field 'index': ${data}`);
     if (typeof data['params'] === 'undefined')
       throw new Error(`Response is missing required field 'params': ${data}`);
-    return new Asset(
-      data['index'],
-      AssetParams.from_obj_for_encoding(data['params'])
-    );
+    return new Asset({
+      index: data['index'],
+      params: AssetParams.from_obj_for_encoding(data['params']),
+    });
     /* eslint-enable dot-notation */
   }
 }
@@ -1078,11 +1122,15 @@ export class AssetHolding extends BaseModel {
    * @param assetId - Asset ID of the holding.
    * @param isFrozen - (f) whether or not the holding is frozen.
    */
-  constructor(
-    amount: number | bigint,
-    assetId: number | bigint,
-    isFrozen: boolean
-  ) {
+  constructor({
+    amount,
+    assetId,
+    isFrozen,
+  }: {
+    amount: number | bigint;
+    assetId: number | bigint;
+    isFrozen: boolean;
+  }) {
     super();
     this.amount = amount;
     this.assetId = assetId;
@@ -1106,11 +1154,11 @@ export class AssetHolding extends BaseModel {
       throw new Error(
         `Response is missing required field 'is-frozen': ${data}`
       );
-    return new AssetHolding(
-      data['amount'],
-      data['asset-id'],
-      data['is-frozen']
-    );
+    return new AssetHolding({
+      amount: data['amount'],
+      assetId: data['asset-id'],
+      isFrozen: data['is-frozen'],
+    });
     /* eslint-enable dot-notation */
   }
 }
@@ -1361,7 +1409,7 @@ export class BlockHashResponse extends BaseModel {
    * Creates a new `BlockHashResponse` object.
    * @param blockhash - Block header hash.
    */
-  constructor(blockhash: string) {
+  constructor({ blockhash }: { blockhash: string }) {
     super();
     this.blockhash = blockhash;
 
@@ -1377,7 +1425,9 @@ export class BlockHashResponse extends BaseModel {
       throw new Error(
         `Response is missing required field 'blockHash': ${data}`
       );
-    return new BlockHashResponse(data['blockHash']);
+    return new BlockHashResponse({
+      blockhash: data['blockHash'],
+    });
     /* eslint-enable dot-notation */
   }
 }
@@ -1403,7 +1453,13 @@ export class BlockResponse extends BaseModel {
    * @param cert - Optional certificate object. This is only included when the format is set to
    * message pack.
    */
-  constructor(block: BlockHeader, cert?: Record<string, any>) {
+  constructor({
+    block,
+    cert,
+  }: {
+    block: BlockHeader;
+    cert?: Record<string, any>;
+  }) {
     super();
     this.block = block;
     this.cert = cert;
@@ -1419,7 +1475,10 @@ export class BlockResponse extends BaseModel {
     /* eslint-disable dot-notation */
     if (typeof data['block'] === 'undefined')
       throw new Error(`Response is missing required field 'block': ${data}`);
-    return new BlockResponse(data['block'], data['cert']);
+    return new BlockResponse({
+      block: data['block'],
+      cert: data['cert'],
+    });
     /* eslint-enable dot-notation */
   }
 }
@@ -1443,7 +1502,13 @@ export class Box extends BaseModel {
    * @param name - (name) box name, base64 encoded
    * @param value - (value) box value, base64 encoded.
    */
-  constructor(name: string | Uint8Array, value: string | Uint8Array) {
+  constructor({
+    name,
+    value,
+  }: {
+    name: string | Uint8Array;
+    value: string | Uint8Array;
+  }) {
     super();
     this.name =
       typeof name === 'string'
@@ -1467,7 +1532,10 @@ export class Box extends BaseModel {
       throw new Error(`Response is missing required field 'name': ${data}`);
     if (typeof data['value'] === 'undefined')
       throw new Error(`Response is missing required field 'value': ${data}`);
-    return new Box(data['name'], data['value']);
+    return new Box({
+      name: data['name'],
+      value: data['value'],
+    });
     /* eslint-enable dot-notation */
   }
 }
@@ -1485,7 +1553,7 @@ export class BoxDescriptor extends BaseModel {
    * Creates a new `BoxDescriptor` object.
    * @param name - Base64 encoded box name
    */
-  constructor(name: string | Uint8Array) {
+  constructor({ name }: { name: string | Uint8Array }) {
     super();
     this.name =
       typeof name === 'string'
@@ -1502,7 +1570,9 @@ export class BoxDescriptor extends BaseModel {
     /* eslint-disable dot-notation */
     if (typeof data['name'] === 'undefined')
       throw new Error(`Response is missing required field 'name': ${data}`);
-    return new BoxDescriptor(data['name']);
+    return new BoxDescriptor({
+      name: data['name'],
+    });
     /* eslint-enable dot-notation */
   }
 }
@@ -1517,7 +1587,7 @@ export class BoxesResponse extends BaseModel {
    * Creates a new `BoxesResponse` object.
    * @param boxes -
    */
-  constructor(boxes: BoxDescriptor[]) {
+  constructor({ boxes }: { boxes: BoxDescriptor[] }) {
     super();
     this.boxes = boxes;
 
@@ -1533,9 +1603,9 @@ export class BoxesResponse extends BaseModel {
       throw new Error(
         `Response is missing required array field 'boxes': ${data}`
       );
-    return new BoxesResponse(
-      data['boxes'].map(BoxDescriptor.from_obj_for_encoding)
-    );
+    return new BoxesResponse({
+      boxes: data['boxes'].map(BoxDescriptor.from_obj_for_encoding),
+    });
     /* eslint-enable dot-notation */
   }
 }
@@ -1626,78 +1696,6 @@ export class BuildVersion extends BaseModel {
   }
 }
 
-/**
- *
- */
-export class CatchpointAbortResponse extends BaseModel {
-  /**
-   * Catchup abort response string
-   */
-  public catchupMessage: string;
-
-  /**
-   * Creates a new `CatchpointAbortResponse` object.
-   * @param catchupMessage - Catchup abort response string
-   */
-  constructor(catchupMessage: string) {
-    super();
-    this.catchupMessage = catchupMessage;
-
-    this.attribute_map = {
-      catchupMessage: 'catchup-message',
-    };
-  }
-
-  // eslint-disable-next-line camelcase
-  static from_obj_for_encoding(
-    data: Record<string, any>
-  ): CatchpointAbortResponse {
-    /* eslint-disable dot-notation */
-    if (typeof data['catchup-message'] === 'undefined')
-      throw new Error(
-        `Response is missing required field 'catchup-message': ${data}`
-      );
-    return new CatchpointAbortResponse(data['catchup-message']);
-    /* eslint-enable dot-notation */
-  }
-}
-
-/**
- *
- */
-export class CatchpointStartResponse extends BaseModel {
-  /**
-   * Catchup start response string
-   */
-  public catchupMessage: string;
-
-  /**
-   * Creates a new `CatchpointStartResponse` object.
-   * @param catchupMessage - Catchup start response string
-   */
-  constructor(catchupMessage: string) {
-    super();
-    this.catchupMessage = catchupMessage;
-
-    this.attribute_map = {
-      catchupMessage: 'catchup-message',
-    };
-  }
-
-  // eslint-disable-next-line camelcase
-  static from_obj_for_encoding(
-    data: Record<string, any>
-  ): CatchpointStartResponse {
-    /* eslint-disable dot-notation */
-    if (typeof data['catchup-message'] === 'undefined')
-      throw new Error(
-        `Response is missing required field 'catchup-message': ${data}`
-      );
-    return new CatchpointStartResponse(data['catchup-message']);
-    /* eslint-enable dot-notation */
-  }
-}
-
 /**
  * Teal compile Result
  */
@@ -1723,7 +1721,15 @@ export class CompileResponse extends BaseModel {
    * @param result - base64 encoded program bytes
    * @param sourcemap - JSON of the source map
    */
-  constructor(hash: string, result: string, sourcemap?: Record<string, any>) {
+  constructor({
+    hash,
+    result,
+    sourcemap,
+  }: {
+    hash: string;
+    result: string;
+    sourcemap?: Record<string, any>;
+  }) {
     super();
     this.hash = hash;
     this.result = result;
@@ -1743,7 +1749,11 @@ export class CompileResponse extends BaseModel {
       throw new Error(`Response is missing required field 'hash': ${data}`);
     if (typeof data['result'] === 'undefined')
       throw new Error(`Response is missing required field 'result': ${data}`);
-    return new CompileResponse(data['hash'], data['result'], data['sourcemap']);
+    return new CompileResponse({
+      hash: data['hash'],
+      result: data['result'],
+      sourcemap: data['sourcemap'],
+    });
     /* eslint-enable dot-notation */
   }
 }
@@ -1761,7 +1771,7 @@ export class DisassembleResponse extends BaseModel {
    * Creates a new `DisassembleResponse` object.
    * @param result - disassembled Teal code
    */
-  constructor(result: string) {
+  constructor({ result }: { result: string }) {
     super();
     this.result = result;
 
@@ -1775,7 +1785,9 @@ export class DisassembleResponse extends BaseModel {
     /* eslint-disable dot-notation */
     if (typeof data['result'] === 'undefined')
       throw new Error(`Response is missing required field 'result': ${data}`);
-    return new DisassembleResponse(data['result']);
+    return new DisassembleResponse({
+      result: data['result'],
+    });
     /* eslint-enable dot-notation */
   }
 }
@@ -1922,7 +1934,15 @@ export class DryrunResponse extends BaseModel {
    * @param protocolVersion - Protocol version is the protocol version Dryrun was operated under.
    * @param txns -
    */
-  constructor(error: string, protocolVersion: string, txns: DryrunTxnResult[]) {
+  constructor({
+    error,
+    protocolVersion,
+    txns,
+  }: {
+    error: string;
+    protocolVersion: string;
+    txns: DryrunTxnResult[];
+  }) {
     super();
     this.error = error;
     this.protocolVersion = protocolVersion;
@@ -1948,11 +1968,11 @@ export class DryrunResponse extends BaseModel {
       throw new Error(
         `Response is missing required array field 'txns': ${data}`
       );
-    return new DryrunResponse(
-      data['error'],
-      data['protocol-version'],
-      data['txns'].map(DryrunTxnResult.from_obj_for_encoding)
-    );
+    return new DryrunResponse({
+      error: data['error'],
+      protocolVersion: data['protocol-version'],
+      txns: data['txns'].map(DryrunTxnResult.from_obj_for_encoding),
+    });
     /* eslint-enable dot-notation */
   }
 }
@@ -1984,12 +2004,17 @@ export class DryrunSource extends BaseModel {
    * @param txnIndex -
    * @param appIndex -
    */
-  constructor(
-    fieldName: string,
-    source: string,
-    txnIndex: number | bigint,
-    appIndex: number | bigint
-  ) {
+  constructor({
+    fieldName,
+    source,
+    txnIndex,
+    appIndex,
+  }: {
+    fieldName: string;
+    source: string;
+    txnIndex: number | bigint;
+    appIndex: number | bigint;
+  }) {
     super();
     this.fieldName = fieldName;
     this.source = source;
@@ -2021,12 +2046,12 @@ export class DryrunSource extends BaseModel {
       throw new Error(
         `Response is missing required field 'app-index': ${data}`
       );
-    return new DryrunSource(
-      data['field-name'],
-      data['source'],
-      data['txn-index'],
-      data['app-index']
-    );
+    return new DryrunSource({
+      fieldName: data['field-name'],
+      source: data['source'],
+      txnIndex: data['txn-index'],
+      appIndex: data['app-index'],
+    });
     /* eslint-enable dot-notation */
   }
 }
@@ -2140,12 +2165,6 @@ export class DryrunTxnResult extends BaseModel {
    */
   public budgetConsumed?: number | bigint;
 
-  /**
-   * Net cost of app execution. Field is DEPRECATED and is subject for removal.
-   * Instead, use `budget-added` and `budget-consumed.
-   */
-  public cost?: number | bigint;
-
   /**
    * Application state delta.
    */
@@ -2171,8 +2190,6 @@ export class DryrunTxnResult extends BaseModel {
    * @param appCallTrace -
    * @param budgetAdded - Budget added during execution of app call transaction.
    * @param budgetConsumed - Budget consumed during execution of app call transaction.
-   * @param cost - Net cost of app execution. Field is DEPRECATED and is subject for removal.
-   * Instead, use `budget-added` and `budget-consumed.
    * @param globalDelta - Application state delta.
    * @param localDeltas -
    * @param logicSigDisassembly - Disassembled lsig program line by line.
@@ -2186,7 +2203,6 @@ export class DryrunTxnResult extends BaseModel {
     appCallTrace,
     budgetAdded,
     budgetConsumed,
-    cost,
     globalDelta,
     localDeltas,
     logicSigDisassembly,
@@ -2199,7 +2215,6 @@ export class DryrunTxnResult extends BaseModel {
     appCallTrace?: DryrunState[];
     budgetAdded?: number | bigint;
     budgetConsumed?: number | bigint;
-    cost?: number | bigint;
     globalDelta?: EvalDeltaKeyValue[];
     localDeltas?: AccountStateDelta[];
     logicSigDisassembly?: string[];
@@ -2213,7 +2228,6 @@ export class DryrunTxnResult extends BaseModel {
     this.appCallTrace = appCallTrace;
     this.budgetAdded = budgetAdded;
     this.budgetConsumed = budgetConsumed;
-    this.cost = cost;
     this.globalDelta = globalDelta;
     this.localDeltas = localDeltas;
     this.logicSigDisassembly = logicSigDisassembly;
@@ -2227,7 +2241,6 @@ export class DryrunTxnResult extends BaseModel {
       appCallTrace: 'app-call-trace',
       budgetAdded: 'budget-added',
       budgetConsumed: 'budget-consumed',
-      cost: 'cost',
       globalDelta: 'global-delta',
       localDeltas: 'local-deltas',
       logicSigDisassembly: 'logic-sig-disassembly',
@@ -2253,7 +2266,6 @@ export class DryrunTxnResult extends BaseModel {
           : undefined,
       budgetAdded: data['budget-added'],
       budgetConsumed: data['budget-consumed'],
-      cost: data['cost'],
       globalDelta:
         typeof data['global-delta'] !== 'undefined'
           ? data['global-delta'].map(EvalDeltaKeyValue.from_obj_for_encoding)
@@ -2287,7 +2299,13 @@ export class ErrorResponse extends BaseModel {
    * @param message -
    * @param data -
    */
-  constructor(message: string, data?: Record<string, any>) {
+  constructor({
+    message,
+    data,
+  }: {
+    message: string;
+    data?: Record<string, any>;
+  }) {
     super();
     this.message = message;
     this.data = data;
@@ -2303,7 +2321,10 @@ export class ErrorResponse extends BaseModel {
     /* eslint-disable dot-notation */
     if (typeof data['message'] === 'undefined')
       throw new Error(`Response is missing required field 'message': ${data}`);
-    return new ErrorResponse(data['message'], data['data']);
+    return new ErrorResponse({
+      message: data['message'],
+      data: data['data'],
+    });
     /* eslint-enable dot-notation */
   }
 }
@@ -2333,7 +2354,15 @@ export class EvalDelta extends BaseModel {
    * @param bytes - (bs) bytes value.
    * @param uint - (ui) uint value.
    */
-  constructor(action: number | bigint, bytes?: string, uint?: number | bigint) {
+  constructor({
+    action,
+    bytes,
+    uint,
+  }: {
+    action: number | bigint;
+    bytes?: string;
+    uint?: number | bigint;
+  }) {
     super();
     this.action = action;
     this.bytes = bytes;
@@ -2351,7 +2380,11 @@ export class EvalDelta extends BaseModel {
     /* eslint-disable dot-notation */
     if (typeof data['action'] === 'undefined')
       throw new Error(`Response is missing required field 'action': ${data}`);
-    return new EvalDelta(data['action'], data['bytes'], data['uint']);
+    return new EvalDelta({
+      action: data['action'],
+      bytes: data['bytes'],
+      uint: data['uint'],
+    });
     /* eslint-enable dot-notation */
   }
 }
@@ -2372,7 +2405,7 @@ export class EvalDeltaKeyValue extends BaseModel {
    * @param key -
    * @param value - Represents a TEAL value delta.
    */
-  constructor(key: string, value: EvalDelta) {
+  constructor({ key, value }: { key: string; value: EvalDelta }) {
     super();
     this.key = key;
     this.value = value;
@@ -2390,10 +2423,10 @@ export class EvalDeltaKeyValue extends BaseModel {
       throw new Error(`Response is missing required field 'key': ${data}`);
     if (typeof data['value'] === 'undefined')
       throw new Error(`Response is missing required field 'value': ${data}`);
-    return new EvalDeltaKeyValue(
-      data['key'],
-      EvalDelta.from_obj_for_encoding(data['value'])
-    );
+    return new EvalDeltaKeyValue({
+      key: data['key'],
+      value: EvalDelta.from_obj_for_encoding(data['value']),
+    });
     /* eslint-enable dot-notation */
   }
 }
@@ -2425,11 +2458,15 @@ export class LightBlockHeaderProof extends BaseModel {
    * @param treedepth - Represents the depth of the tree that is being proven, i.e. the number of edges
    * from a leaf to the root.
    */
-  constructor(
-    index: number | bigint,
-    proof: string | Uint8Array,
-    treedepth: number | bigint
-  ) {
+  constructor({
+    index,
+    proof,
+    treedepth,
+  }: {
+    index: number | bigint;
+    proof: string | Uint8Array;
+    treedepth: number | bigint;
+  }) {
     super();
     this.index = index;
     this.proof =
@@ -2458,11 +2495,11 @@ export class LightBlockHeaderProof extends BaseModel {
       throw new Error(
         `Response is missing required field 'treedepth': ${data}`
       );
-    return new LightBlockHeaderProof(
-      data['index'],
-      data['proof'],
-      data['treedepth']
-    );
+    return new LightBlockHeaderProof({
+      index: data['index'],
+      proof: data['proof'],
+      treedepth: data['treedepth'],
+    });
     /* eslint-enable dot-notation */
   }
 }
@@ -2972,10 +3009,13 @@ export class PendingTransactionsResponse extends BaseModel {
    * @param topTransactions - An array of signed transaction objects.
    * @param totalTransactions - Total number of transactions in the pool.
    */
-  constructor(
-    topTransactions: EncodedSignedTransaction[],
-    totalTransactions: number | bigint
-  ) {
+  constructor({
+    topTransactions,
+    totalTransactions,
+  }: {
+    topTransactions: EncodedSignedTransaction[];
+    totalTransactions: number | bigint;
+  }) {
     super();
     this.topTransactions = topTransactions;
     this.totalTransactions = totalTransactions;
@@ -2999,10 +3039,10 @@ export class PendingTransactionsResponse extends BaseModel {
       throw new Error(
         `Response is missing required field 'total-transactions': ${data}`
       );
-    return new PendingTransactionsResponse(
-      data['top-transactions'],
-      data['total-transactions']
-    );
+    return new PendingTransactionsResponse({
+      topTransactions: data['top-transactions'],
+      totalTransactions: data['total-transactions'],
+    });
     /* eslint-enable dot-notation */
   }
 }
@@ -3020,7 +3060,7 @@ export class PostTransactionsResponse extends BaseModel {
    * Creates a new `PostTransactionsResponse` object.
    * @param txid - encoding of the transaction hash.
    */
-  constructor(txid: string) {
+  constructor({ txid }: { txid: string }) {
     super();
     this.txid = txid;
 
@@ -3036,7 +3076,9 @@ export class PostTransactionsResponse extends BaseModel {
     /* eslint-disable dot-notation */
     if (typeof data['txId'] === 'undefined')
       throw new Error(`Response is missing required field 'txId': ${data}`);
-    return new PostTransactionsResponse(data['txId']);
+    return new PostTransactionsResponse({
+      txid: data['txId'],
+    });
     /* eslint-enable dot-notation */
   }
 }
@@ -3060,7 +3102,13 @@ export class StateProof extends BaseModel {
    * @param message - Represents the message that the state proofs are attesting to.
    * @param stateproof - The encoded StateProof for the message.
    */
-  constructor(message: StateProofMessage, stateproof: string | Uint8Array) {
+  constructor({
+    message,
+    stateproof,
+  }: {
+    message: StateProofMessage;
+    stateproof: string | Uint8Array;
+  }) {
     super();
     this.message = message;
     this.stateproof =
@@ -3083,10 +3131,10 @@ export class StateProof extends BaseModel {
       throw new Error(
         `Response is missing required field 'StateProof': ${data}`
       );
-    return new StateProof(
-      StateProofMessage.from_obj_for_encoding(data['Message']),
-      data['StateProof']
-    );
+    return new StateProof({
+      message: StateProofMessage.from_obj_for_encoding(data['Message']),
+      stateproof: data['StateProof'],
+    });
     /* eslint-enable dot-notation */
   }
 }
@@ -3226,11 +3274,15 @@ export class SupplyResponse extends BaseModel {
    * @param onlineMoney - OnlineMoney
    * @param totalMoney - TotalMoney
    */
-  constructor(
-    currentRound: number | bigint,
-    onlineMoney: number | bigint,
-    totalMoney: number | bigint
-  ) {
+  constructor({
+    currentRound,
+    onlineMoney,
+    totalMoney,
+  }: {
+    currentRound: number | bigint;
+    onlineMoney: number | bigint;
+    totalMoney: number | bigint;
+  }) {
     super();
     this.currentRound = currentRound;
     this.onlineMoney = onlineMoney;
@@ -3258,11 +3310,11 @@ export class SupplyResponse extends BaseModel {
       throw new Error(
         `Response is missing required field 'total-money': ${data}`
       );
-    return new SupplyResponse(
-      data['current_round'],
-      data['online-money'],
-      data['total-money']
-    );
+    return new SupplyResponse({
+      currentRound: data['current_round'],
+      onlineMoney: data['online-money'],
+      totalMoney: data['total-money'],
+    });
     /* eslint-enable dot-notation */
   }
 }
@@ -3283,7 +3335,7 @@ export class TealKeyValue extends BaseModel {
    * @param key -
    * @param value - Represents a TEAL value.
    */
-  constructor(key: string, value: TealValue) {
+  constructor({ key, value }: { key: string; value: TealValue }) {
     super();
     this.key = key;
     this.value = value;
@@ -3301,10 +3353,10 @@ export class TealKeyValue extends BaseModel {
       throw new Error(`Response is missing required field 'key': ${data}`);
     if (typeof data['value'] === 'undefined')
       throw new Error(`Response is missing required field 'value': ${data}`);
-    return new TealKeyValue(
-      data['key'],
-      TealValue.from_obj_for_encoding(data['value'])
-    );
+    return new TealKeyValue({
+      key: data['key'],
+      value: TealValue.from_obj_for_encoding(data['value']),
+    });
     /* eslint-enable dot-notation */
   }
 }
@@ -3334,7 +3386,15 @@ export class TealValue extends BaseModel {
    * @param bytes - (tb) bytes value.
    * @param uint - (ui) uint value.
    */
-  constructor(type: number | bigint, bytes: string, uint: number | bigint) {
+  constructor({
+    type,
+    bytes,
+    uint,
+  }: {
+    type: number | bigint;
+    bytes: string;
+    uint: number | bigint;
+  }) {
     super();
     this.type = type;
     this.bytes = bytes;
@@ -3356,7 +3416,11 @@ export class TealValue extends BaseModel {
       throw new Error(`Response is missing required field 'bytes': ${data}`);
     if (typeof data['uint'] === 'undefined')
       throw new Error(`Response is missing required field 'uint': ${data}`);
-    return new TealValue(data['type'], data['bytes'], data['uint']);
+    return new TealValue({
+      type: data['type'],
+      bytes: data['bytes'],
+      uint: data['uint'],
+    });
     /* eslint-enable dot-notation */
   }
 }
@@ -3611,12 +3675,17 @@ export class Version extends BaseModel {
    * @param genesisId -
    * @param versions -
    */
-  constructor(
-    build: BuildVersion,
-    genesisHashB64: string | Uint8Array,
-    genesisId: string,
-    versions: string[]
-  ) {
+  constructor({
+    build,
+    genesisHashB64,
+    genesisId,
+    versions,
+  }: {
+    build: BuildVersion;
+    genesisHashB64: string | Uint8Array;
+    genesisId: string;
+    versions: string[];
+  }) {
     super();
     this.build = build;
     this.genesisHashB64 =
@@ -3651,12 +3720,12 @@ export class Version extends BaseModel {
       throw new Error(
         `Response is missing required array field 'versions': ${data}`
       );
-    return new Version(
-      BuildVersion.from_obj_for_encoding(data['build']),
-      data['genesis_hash_b64'],
-      data['genesis_id'],
-      data['versions']
-    );
+    return new Version({
+      build: BuildVersion.from_obj_for_encoding(data['build']),
+      genesisHashB64: data['genesis_hash_b64'],
+      genesisId: data['genesis_id'],
+      versions: data['versions'],
+    });
     /* eslint-enable dot-notation */
   }
 }
diff --git a/src/client/v2/indexer/lookupAssetTransactions.ts b/src/client/v2/indexer/lookupAssetTransactions.ts
index 45f1589..27b95b6 100644
--- a/src/client/v2/indexer/lookupAssetTransactions.ts
+++ b/src/client/v2/indexer/lookupAssetTransactions.ts
@@ -176,14 +176,6 @@ export default class LookupAssetTransactions extends JSONRequest {
     return this;
   }
 
-  /**
-   * @deprecated Redundant query parameter. Asset ID is already passed into the method.
-   */
-  assetID(id: number) {
-    this.query['asset-id'] = id;
-    return this;
-  }
-
   /**
    * Maximum number of results to return.
    *
diff --git a/src/dryrun.ts b/src/dryrun.ts
index abc23db..5755e74 100644
--- a/src/dryrun.ts
+++ b/src/dryrun.ts
@@ -92,22 +92,22 @@ export async function createDryrun({
       // Create application,
       if (t.txn.appIndex === undefined || t.txn.appIndex === 0) {
         appInfos.push(
-          new Application(
-            defaultAppId,
-            new ApplicationParams({
+          new Application({
+            id: defaultAppId,
+            params: new ApplicationParams({
               creator: encodeAddress(t.txn.from.publicKey),
               approvalProgram: t.txn.appApprovalProgram,
               clearStateProgram: t.txn.appClearProgram,
-              localStateSchema: new ApplicationStateSchema(
-                t.txn.appLocalInts,
-                t.txn.appLocalByteSlices
-              ),
-              globalStateSchema: new ApplicationStateSchema(
-                t.txn.appGlobalInts,
-                t.txn.appGlobalByteSlices
-              ),
-            })
-          )
+              localStateSchema: new ApplicationStateSchema({
+                numUint: t.txn.appLocalInts,
+                numByteSlice: t.txn.appLocalByteSlices,
+              }),
+              globalStateSchema: new ApplicationStateSchema({
+                numUint: t.txn.appGlobalInts,
+                numByteSlice: t.txn.appGlobalByteSlices,
+              }),
+            }),
+          })
         );
       } else {
         apps.push(t.txn.appIndex);
diff --git a/src/logic/langspec.json b/src/logic/langspec.json
deleted file mode 100644
index 5fa35c4..0000000
--- a/src/logic/langspec.json
+++ /dev/null
@@ -1,2014 +0,0 @@
-{
-  "EvalMaxVersion": 6,
-  "LogicSigVersion": 5,
-  "Ops": [
-    {
-      "Opcode": 0,
-      "Name": "err",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "Fail immediately.",
-      "Groups": ["Flow Control"]
-    },
-    {
-      "Opcode": 1,
-      "Name": "sha256",
-      "Args": "B",
-      "Returns": "B",
-      "Cost": 35,
-      "Size": 1,
-      "Doc": "SHA256 hash of value A, yields [32]byte",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 2,
-      "Name": "keccak256",
-      "Args": "B",
-      "Returns": "B",
-      "Cost": 130,
-      "Size": 1,
-      "Doc": "Keccak256 hash of value A, yields [32]byte",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 3,
-      "Name": "sha512_256",
-      "Args": "B",
-      "Returns": "B",
-      "Cost": 45,
-      "Size": 1,
-      "Doc": "SHA512_256 hash of value A, yields [32]byte",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 4,
-      "Name": "ed25519verify",
-      "Args": "BBB",
-      "Returns": "U",
-      "Cost": 1900,
-      "Size": 1,
-      "Doc": "for (data A, signature B, pubkey C) verify the signature of (\"ProgData\" || program_hash || data) against the pubkey =\u003e {0 or 1}",
-      "DocExtra": "The 32 byte public key is the last element on the stack, preceded by the 64 byte signature at the second-to-last element on the stack, preceded by the data which was signed at the third-to-last element on the stack.",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 5,
-      "Name": "ecdsa_verify",
-      "Args": "BBBBB",
-      "Returns": "U",
-      "Cost": 1700,
-      "Size": 2,
-      "Doc": "for (data A, signature B, C and pubkey D, E) verify the signature of the data against the pubkey =\u003e {0 or 1}",
-      "DocExtra": "The 32 byte Y-component of a public key is the last element on the stack, preceded by X-component of a pubkey, preceded by S and R components of a signature, preceded by the data that is fifth element on the stack. All values are big-endian encoded. The signed data must be 32 bytes long, and signatures in lower-S form are only accepted.",
-      "ImmediateNote": "{uint8 curve index}",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 6,
-      "Name": "ecdsa_pk_decompress",
-      "Args": "B",
-      "Returns": "BB",
-      "Cost": 650,
-      "Size": 2,
-      "Doc": "decompress pubkey A into components X, Y",
-      "DocExtra": "The 33 byte public key in a compressed form to be decompressed into X and Y (top) components. All values are big-endian encoded.",
-      "ImmediateNote": "{uint8 curve index}",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 7,
-      "Name": "ecdsa_pk_recover",
-      "Args": "BUBB",
-      "Returns": "BB",
-      "Cost": 2000,
-      "Size": 2,
-      "Doc": "for (data A, recovery id B, signature C, D) recover a public key",
-      "DocExtra": "S (top) and R elements of a signature, recovery id and data (bottom) are expected on the stack and used to deriver a public key. All values are big-endian encoded. The signed data must be 32 bytes long.",
-      "ImmediateNote": "{uint8 curve index}",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 8,
-      "Name": "+",
-      "Args": "UU",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "A plus B. Fail on overflow.",
-      "DocExtra": "Overflow is an error condition which halts execution and fails the transaction. Full precision is available from `addw`.",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 9,
-      "Name": "-",
-      "Args": "UU",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "A minus B. Fail if B \u003e A.",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 10,
-      "Name": "/",
-      "Args": "UU",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "A divided by B (truncated division). Fail if B == 0.",
-      "DocExtra": "`divmodw` is available to divide the two-element values produced by `mulw` and `addw`.",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 11,
-      "Name": "*",
-      "Args": "UU",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "A times B. Fail on overflow.",
-      "DocExtra": "Overflow is an error condition which halts execution and fails the transaction. Full precision is available from `mulw`.",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 12,
-      "Name": "\u003c",
-      "Args": "UU",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "A less than B =\u003e {0 or 1}",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 13,
-      "Name": "\u003e",
-      "Args": "UU",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "A greater than B =\u003e {0 or 1}",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 14,
-      "Name": "\u003c=",
-      "Args": "UU",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "A less than or equal to B =\u003e {0 or 1}",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 15,
-      "Name": "\u003e=",
-      "Args": "UU",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "A greater than or equal to B =\u003e {0 or 1}",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 16,
-      "Name": "\u0026\u0026",
-      "Args": "UU",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "A is not zero and B is not zero =\u003e {0 or 1}",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 17,
-      "Name": "||",
-      "Args": "UU",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "A is not zero or B is not zero =\u003e {0 or 1}",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 18,
-      "Name": "==",
-      "Args": "..",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "A is equal to B =\u003e {0 or 1}",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 19,
-      "Name": "!=",
-      "Args": "..",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "A is not equal to B =\u003e {0 or 1}",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 20,
-      "Name": "!",
-      "Args": "U",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "A == 0 yields 1; else 0",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 21,
-      "Name": "len",
-      "Args": "B",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "yields length of byte value A",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 22,
-      "Name": "itob",
-      "Args": "U",
-      "Returns": "B",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "converts uint64 A to big endian bytes",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 23,
-      "Name": "btoi",
-      "Args": "B",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "converts bytes A as big endian to uint64",
-      "DocExtra": "`btoi` fails if the input is longer than 8 bytes.",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 24,
-      "Name": "%",
-      "Args": "UU",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "A modulo B. Fail if B == 0.",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 25,
-      "Name": "|",
-      "Args": "UU",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "A bitwise-or B",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 26,
-      "Name": "\u0026",
-      "Args": "UU",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "A bitwise-and B",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 27,
-      "Name": "^",
-      "Args": "UU",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "A bitwise-xor B",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 28,
-      "Name": "~",
-      "Args": "U",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "bitwise invert value A",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 29,
-      "Name": "mulw",
-      "Args": "UU",
-      "Returns": "UU",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "A times B as a 128-bit result in two uint64s. X is the high 64 bits, Y is the low",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 30,
-      "Name": "addw",
-      "Args": "UU",
-      "Returns": "UU",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "A plus B as a 128-bit result. X is the carry-bit, Y is the low-order 64 bits.",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 31,
-      "Name": "divmodw",
-      "Args": "UUUU",
-      "Returns": "UUUU",
-      "Cost": 20,
-      "Size": 1,
-      "Doc": "W,X = (A,B / C,D); Y,Z = (A,B modulo C,D)",
-      "DocExtra": "The notation J,K indicates that two uint64 values J and K are interpreted as a uint128 value, with J as the high uint64 and K the low.",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 32,
-      "Name": "intcblock",
-      "Cost": 1,
-      "Size": 0,
-      "Doc": "prepare block of uint64 constants for use by intc",
-      "DocExtra": "`intcblock` loads following program bytes into an array of integer constants in the evaluator. These integer constants can be referred to by `intc` and `intc_*` which will push the value onto the stack. Subsequent calls to `intcblock` reset and replace the integer constants available to the script.",
-      "ImmediateNote": "{varuint length} [{varuint value}, ...]",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 33,
-      "Name": "intc",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 2,
-      "Doc": "Ith constant from intcblock",
-      "ImmediateNote": "{uint8 int constant index}",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 34,
-      "Name": "intc_0",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "constant 0 from intcblock",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 35,
-      "Name": "intc_1",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "constant 1 from intcblock",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 36,
-      "Name": "intc_2",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "constant 2 from intcblock",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 37,
-      "Name": "intc_3",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "constant 3 from intcblock",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 38,
-      "Name": "bytecblock",
-      "Cost": 1,
-      "Size": 0,
-      "Doc": "prepare block of byte-array constants for use by bytec",
-      "DocExtra": "`bytecblock` loads the following program bytes into an array of byte-array constants in the evaluator. These constants can be referred to by `bytec` and `bytec_*` which will push the value onto the stack. Subsequent calls to `bytecblock` reset and replace the bytes constants available to the script.",
-      "ImmediateNote": "{varuint length} [({varuint value length} bytes), ...]",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 39,
-      "Name": "bytec",
-      "Returns": "B",
-      "Cost": 1,
-      "Size": 2,
-      "Doc": "Ith constant from bytecblock",
-      "ImmediateNote": "{uint8 byte constant index}",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 40,
-      "Name": "bytec_0",
-      "Returns": "B",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "constant 0 from bytecblock",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 41,
-      "Name": "bytec_1",
-      "Returns": "B",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "constant 1 from bytecblock",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 42,
-      "Name": "bytec_2",
-      "Returns": "B",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "constant 2 from bytecblock",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 43,
-      "Name": "bytec_3",
-      "Returns": "B",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "constant 3 from bytecblock",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 44,
-      "Name": "arg",
-      "Returns": "B",
-      "Cost": 1,
-      "Size": 2,
-      "Doc": "Nth LogicSig argument",
-      "ImmediateNote": "{uint8 arg index N}",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 45,
-      "Name": "arg_0",
-      "Returns": "B",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "LogicSig argument 0",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 46,
-      "Name": "arg_1",
-      "Returns": "B",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "LogicSig argument 1",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 47,
-      "Name": "arg_2",
-      "Returns": "B",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "LogicSig argument 2",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 48,
-      "Name": "arg_3",
-      "Returns": "B",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "LogicSig argument 3",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 49,
-      "Name": "txn",
-      "Returns": ".",
-      "Cost": 1,
-      "Size": 2,
-      "ArgEnum": [
-        "Sender",
-        "Fee",
-        "FirstValid",
-        "FirstValidTime",
-        "LastValid",
-        "Note",
-        "Lease",
-        "Receiver",
-        "Amount",
-        "CloseRemainderTo",
-        "VotePK",
-        "SelectionPK",
-        "VoteFirst",
-        "VoteLast",
-        "VoteKeyDilution",
-        "Type",
-        "TypeEnum",
-        "XferAsset",
-        "AssetAmount",
-        "AssetSender",
-        "AssetReceiver",
-        "AssetCloseTo",
-        "GroupIndex",
-        "TxID",
-        "ApplicationID",
-        "OnCompletion",
-        "ApplicationArgs",
-        "NumAppArgs",
-        "Accounts",
-        "NumAccounts",
-        "ApprovalProgram",
-        "ClearStateProgram",
-        "RekeyTo",
-        "ConfigAsset",
-        "ConfigAssetTotal",
-        "ConfigAssetDecimals",
-        "ConfigAssetDefaultFrozen",
-        "ConfigAssetUnitName",
-        "ConfigAssetName",
-        "ConfigAssetURL",
-        "ConfigAssetMetadataHash",
-        "ConfigAssetManager",
-        "ConfigAssetReserve",
-        "ConfigAssetFreeze",
-        "ConfigAssetClawback",
-        "FreezeAsset",
-        "FreezeAssetAccount",
-        "FreezeAssetFrozen",
-        "Assets",
-        "NumAssets",
-        "Applications",
-        "NumApplications",
-        "GlobalNumUint",
-        "GlobalNumByteSlice",
-        "LocalNumUint",
-        "LocalNumByteSlice",
-        "ExtraProgramPages",
-        "Nonparticipation",
-        "Logs",
-        "NumLogs",
-        "CreatedAssetID",
-        "CreatedApplicationID",
-        "LastLog",
-        "StateProofPK"
-      ],
-      "ArgEnumTypes": "BUUUUBBBUBBBUUUBUUUBBBUBUUBUBUBBBUUUUBBBBBBBBUBUUUUUUUUUUUBUUUBB",
-      "Doc": "field F of current transaction",
-      "DocExtra": "FirstValidTime causes the program to fail. The field is reserved for future use.",
-      "ImmediateNote": "{uint8 transaction field index}",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 50,
-      "Name": "global",
-      "Returns": ".",
-      "Cost": 1,
-      "Size": 2,
-      "Doc": "global field F",
-      "ImmediateNote": "{uint8 global field index}",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 51,
-      "Name": "gtxn",
-      "Returns": ".",
-      "Cost": 1,
-      "Size": 3,
-      "ArgEnum": [
-        "Sender",
-        "Fee",
-        "FirstValid",
-        "FirstValidTime",
-        "LastValid",
-        "Note",
-        "Lease",
-        "Receiver",
-        "Amount",
-        "CloseRemainderTo",
-        "VotePK",
-        "SelectionPK",
-        "VoteFirst",
-        "VoteLast",
-        "VoteKeyDilution",
-        "Type",
-        "TypeEnum",
-        "XferAsset",
-        "AssetAmount",
-        "AssetSender",
-        "AssetReceiver",
-        "AssetCloseTo",
-        "GroupIndex",
-        "TxID",
-        "ApplicationID",
-        "OnCompletion",
-        "ApplicationArgs",
-        "NumAppArgs",
-        "Accounts",
-        "NumAccounts",
-        "ApprovalProgram",
-        "ClearStateProgram",
-        "RekeyTo",
-        "ConfigAsset",
-        "ConfigAssetTotal",
-        "ConfigAssetDecimals",
-        "ConfigAssetDefaultFrozen",
-        "ConfigAssetUnitName",
-        "ConfigAssetName",
-        "ConfigAssetURL",
-        "ConfigAssetMetadataHash",
-        "ConfigAssetManager",
-        "ConfigAssetReserve",
-        "ConfigAssetFreeze",
-        "ConfigAssetClawback",
-        "FreezeAsset",
-        "FreezeAssetAccount",
-        "FreezeAssetFrozen",
-        "Assets",
-        "NumAssets",
-        "Applications",
-        "NumApplications",
-        "GlobalNumUint",
-        "GlobalNumByteSlice",
-        "LocalNumUint",
-        "LocalNumByteSlice",
-        "ExtraProgramPages",
-        "Nonparticipation",
-        "Logs",
-        "NumLogs",
-        "CreatedAssetID",
-        "CreatedApplicationID",
-        "LastLog",
-        "StateProofPK"
-      ],
-      "ArgEnumTypes": "BUUUUBBBUBBBUUUBUUUBBBUBUUBUBUBBBUUUUBBBBBBBBUBUUUUUUUUUUUBUUUBB",
-      "Doc": "field F of the Tth transaction in the current group",
-      "DocExtra": "for notes on transaction fields available, see `txn`. If this transaction is _i_ in the group, `gtxn i field` is equivalent to `txn field`.",
-      "ImmediateNote": "{uint8 transaction group index} {uint8 transaction field index}",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 52,
-      "Name": "load",
-      "Returns": ".",
-      "Cost": 1,
-      "Size": 2,
-      "Doc": "Ith scratch space value. All scratch spaces are 0 at program start.",
-      "ImmediateNote": "{uint8 position in scratch space to load from}",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 53,
-      "Name": "store",
-      "Args": ".",
-      "Cost": 1,
-      "Size": 2,
-      "Doc": "store A to the Ith scratch space",
-      "ImmediateNote": "{uint8 position in scratch space to store to}",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 54,
-      "Name": "txna",
-      "Returns": ".",
-      "Cost": 1,
-      "Size": 3,
-      "ArgEnum": [
-        "ApplicationArgs",
-        "Accounts",
-        "Assets",
-        "Applications",
-        "Logs"
-      ],
-      "ArgEnumTypes": "BBUUB",
-      "Doc": "Ith value of the array field F of the current transaction",
-      "ImmediateNote": "{uint8 transaction field index} {uint8 transaction field array index}",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 55,
-      "Name": "gtxna",
-      "Returns": ".",
-      "Cost": 1,
-      "Size": 4,
-      "ArgEnum": [
-        "ApplicationArgs",
-        "Accounts",
-        "Assets",
-        "Applications",
-        "Logs"
-      ],
-      "ArgEnumTypes": "BBUUB",
-      "Doc": "Ith value of the array field F from the Tth transaction in the current group",
-      "ImmediateNote": "{uint8 transaction group index} {uint8 transaction field index} {uint8 transaction field array index}",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 56,
-      "Name": "gtxns",
-      "Args": "U",
-      "Returns": ".",
-      "Cost": 1,
-      "Size": 2,
-      "ArgEnum": [
-        "Sender",
-        "Fee",
-        "FirstValid",
-        "FirstValidTime",
-        "LastValid",
-        "Note",
-        "Lease",
-        "Receiver",
-        "Amount",
-        "CloseRemainderTo",
-        "VotePK",
-        "SelectionPK",
-        "VoteFirst",
-        "VoteLast",
-        "VoteKeyDilution",
-        "Type",
-        "TypeEnum",
-        "XferAsset",
-        "AssetAmount",
-        "AssetSender",
-        "AssetReceiver",
-        "AssetCloseTo",
-        "GroupIndex",
-        "TxID",
-        "ApplicationID",
-        "OnCompletion",
-        "ApplicationArgs",
-        "NumAppArgs",
-        "Accounts",
-        "NumAccounts",
-        "ApprovalProgram",
-        "ClearStateProgram",
-        "RekeyTo",
-        "ConfigAsset",
-        "ConfigAssetTotal",
-        "ConfigAssetDecimals",
-        "ConfigAssetDefaultFrozen",
-        "ConfigAssetUnitName",
-        "ConfigAssetName",
-        "ConfigAssetURL",
-        "ConfigAssetMetadataHash",
-        "ConfigAssetManager",
-        "ConfigAssetReserve",
-        "ConfigAssetFreeze",
-        "ConfigAssetClawback",
-        "FreezeAsset",
-        "FreezeAssetAccount",
-        "FreezeAssetFrozen",
-        "Assets",
-        "NumAssets",
-        "Applications",
-        "NumApplications",
-        "GlobalNumUint",
-        "GlobalNumByteSlice",
-        "LocalNumUint",
-        "LocalNumByteSlice",
-        "ExtraProgramPages",
-        "Nonparticipation",
-        "Logs",
-        "NumLogs",
-        "CreatedAssetID",
-        "CreatedApplicationID",
-        "LastLog",
-        "StateProofPK"
-      ],
-      "ArgEnumTypes": "BUUUUBBBUBBBUUUBUUUBBBUBUUBUBUBBBUUUUBBBBBBBBUBUUUUUUUUUUUBUUUBB",
-      "Doc": "field F of the Ath transaction in the current group",
-      "DocExtra": "for notes on transaction fields available, see `txn`. If top of stack is _i_, `gtxns field` is equivalent to `gtxn _i_ field`. gtxns exists so that _i_ can be calculated, often based on the index of the current transaction.",
-      "ImmediateNote": "{uint8 transaction field index}",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 57,
-      "Name": "gtxnsa",
-      "Args": "U",
-      "Returns": ".",
-      "Cost": 1,
-      "Size": 3,
-      "ArgEnum": [
-        "ApplicationArgs",
-        "Accounts",
-        "Assets",
-        "Applications",
-        "Logs"
-      ],
-      "ArgEnumTypes": "BBUUB",
-      "Doc": "Ith value of the array field F from the Ath transaction in the current group",
-      "ImmediateNote": "{uint8 transaction field index} {uint8 transaction field array index}",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 58,
-      "Name": "gload",
-      "Returns": ".",
-      "Cost": 1,
-      "Size": 3,
-      "Doc": "Ith scratch space value of the Tth transaction in the current group",
-      "DocExtra": "`gload` fails unless the requested transaction is an ApplicationCall and T \u003c GroupIndex.",
-      "ImmediateNote": "{uint8 transaction group index} {uint8 position in scratch space to load from}",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 59,
-      "Name": "gloads",
-      "Args": "U",
-      "Returns": ".",
-      "Cost": 1,
-      "Size": 2,
-      "Doc": "Ith scratch space value of the Ath transaction in the current group",
-      "DocExtra": "`gloads` fails unless the requested transaction is an ApplicationCall and A \u003c GroupIndex.",
-      "ImmediateNote": "{uint8 position in scratch space to load from}",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 60,
-      "Name": "gaid",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 2,
-      "Doc": "ID of the asset or application created in the Tth transaction of the current group",
-      "DocExtra": "`gaid` fails unless the requested transaction created an asset or application and T \u003c GroupIndex.",
-      "ImmediateNote": "{uint8 transaction group index}",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 61,
-      "Name": "gaids",
-      "Args": "U",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "ID of the asset or application created in the Ath transaction of the current group",
-      "DocExtra": "`gaids` fails unless the requested transaction created an asset or application and A \u003c GroupIndex.",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 62,
-      "Name": "loads",
-      "Args": "U",
-      "Returns": ".",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "Ath scratch space value.  All scratch spaces are 0 at program start.",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 63,
-      "Name": "stores",
-      "Args": "U.",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "store B to the Ath scratch space",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 64,
-      "Name": "bnz",
-      "Args": "U",
-      "Cost": 1,
-      "Size": 3,
-      "Doc": "branch to TARGET if value A is not zero",
-      "DocExtra": "The `bnz` instruction opcode 0x40 is followed by two immediate data bytes which are a high byte first and low byte second which together form a 16 bit offset which the instruction may branch to. For a bnz instruction at `pc`, if the last element of the stack is not zero then branch to instruction at `pc + 3 + N`, else proceed to next instruction at `pc + 3`. Branch targets must be aligned instructions. (e.g. Branching to the second byte of a 2 byte op will be rejected.) Starting at v4, the offset is treated as a signed 16 bit integer allowing for backward branches and looping. In prior version (v1 to v3), branch offsets are limited to forward branches only, 0-0x7fff.\n\nAt v2 it became allowed to branch to the end of the program exactly after the last instruction: bnz to byte N (with 0-indexing) was illegal for a TEAL program with N bytes before v2, and is legal after it. This change eliminates the need for a last instruction of no-op as a branch target at the end. (Branching beyond the end--in other words, to a byte larger than N--is still illegal and will cause the program to fail.)",
-      "ImmediateNote": "{int16 branch offset, big endian}",
-      "Groups": ["Flow Control"]
-    },
-    {
-      "Opcode": 65,
-      "Name": "bz",
-      "Args": "U",
-      "Cost": 1,
-      "Size": 3,
-      "Doc": "branch to TARGET if value A is zero",
-      "DocExtra": "See `bnz` for details on how branches work. `bz` inverts the behavior of `bnz`.",
-      "ImmediateNote": "{int16 branch offset, big endian}",
-      "Groups": ["Flow Control"]
-    },
-    {
-      "Opcode": 66,
-      "Name": "b",
-      "Cost": 1,
-      "Size": 3,
-      "Doc": "branch unconditionally to TARGET",
-      "DocExtra": "See `bnz` for details on how branches work. `b` always jumps to the offset.",
-      "ImmediateNote": "{int16 branch offset, big endian}",
-      "Groups": ["Flow Control"]
-    },
-    {
-      "Opcode": 67,
-      "Name": "return",
-      "Args": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "use A as success value; end",
-      "Groups": ["Flow Control"]
-    },
-    {
-      "Opcode": 68,
-      "Name": "assert",
-      "Args": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "immediately fail unless A is a non-zero number",
-      "Groups": ["Flow Control"]
-    },
-    {
-      "Opcode": 72,
-      "Name": "pop",
-      "Args": ".",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "discard A",
-      "Groups": ["Flow Control"]
-    },
-    {
-      "Opcode": 73,
-      "Name": "dup",
-      "Args": ".",
-      "Returns": "..",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "duplicate A",
-      "Groups": ["Flow Control"]
-    },
-    {
-      "Opcode": 74,
-      "Name": "dup2",
-      "Args": "..",
-      "Returns": "....",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "duplicate A and B",
-      "Groups": ["Flow Control"]
-    },
-    {
-      "Opcode": 75,
-      "Name": "dig",
-      "Args": ".",
-      "Returns": "..",
-      "Cost": 1,
-      "Size": 2,
-      "Doc": "Nth value from the top of the stack. dig 0 is equivalent to dup",
-      "ImmediateNote": "{uint8 depth}",
-      "Groups": ["Flow Control"]
-    },
-    {
-      "Opcode": 76,
-      "Name": "swap",
-      "Args": "..",
-      "Returns": "..",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "swaps A and B on stack",
-      "Groups": ["Flow Control"]
-    },
-    {
-      "Opcode": 77,
-      "Name": "select",
-      "Args": "..U",
-      "Returns": ".",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "selects one of two values based on top-of-stack: B if C != 0, else A",
-      "Groups": ["Flow Control"]
-    },
-    {
-      "Opcode": 78,
-      "Name": "cover",
-      "Args": ".",
-      "Returns": ".",
-      "Cost": 1,
-      "Size": 2,
-      "Doc": "remove top of stack, and place it deeper in the stack such that N elements are above it. Fails if stack depth \u003c= N.",
-      "ImmediateNote": "{uint8 depth}",
-      "Groups": ["Flow Control"]
-    },
-    {
-      "Opcode": 79,
-      "Name": "uncover",
-      "Args": ".",
-      "Returns": ".",
-      "Cost": 1,
-      "Size": 2,
-      "Doc": "remove the value at depth N in the stack and shift above items down so the Nth deep value is on top of the stack. Fails if stack depth \u003c= N.",
-      "ImmediateNote": "{uint8 depth}",
-      "Groups": ["Flow Control"]
-    },
-    {
-      "Opcode": 80,
-      "Name": "concat",
-      "Args": "BB",
-      "Returns": "B",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "join A and B",
-      "DocExtra": "`concat` fails if the result would be greater than 4096 bytes.",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 81,
-      "Name": "substring",
-      "Args": "B",
-      "Returns": "B",
-      "Cost": 1,
-      "Size": 3,
-      "Doc": "A range of bytes from A starting at S up to but not including E. If E \u003c S, or either is larger than the array length, the program fails",
-      "ImmediateNote": "{uint8 start position} {uint8 end position}",
-      "Groups": ["Byte Array Manipulation"]
-    },
-    {
-      "Opcode": 82,
-      "Name": "substring3",
-      "Args": "BUU",
-      "Returns": "B",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "A range of bytes from A starting at B up to but not including C. If C \u003c B, or either is larger than the array length, the program fails",
-      "Groups": ["Byte Array Manipulation"]
-    },
-    {
-      "Opcode": 83,
-      "Name": "getbit",
-      "Args": ".U",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "Bth bit of (byte-array or integer) A.",
-      "DocExtra": "see explanation of bit ordering in setbit",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 84,
-      "Name": "setbit",
-      "Args": ".UU",
-      "Returns": ".",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "Copy of (byte-array or integer) A, with the Bth bit set to (0 or 1) C",
-      "DocExtra": "When A is a uint64, index 0 is the least significant bit. Setting bit 3 to 1 on the integer 0 yields 8, or 2^3. When A is a byte array, index 0 is the leftmost bit of the leftmost byte. Setting bits 0 through 11 to 1 in a 4-byte-array of 0s yields the byte array 0xfff00000. Setting bit 3 to 1 on the 1-byte-array 0x00 yields the byte array 0x10.",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 85,
-      "Name": "getbyte",
-      "Args": "BU",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "Bth byte of A, as an integer",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 86,
-      "Name": "setbyte",
-      "Args": "BUU",
-      "Returns": "B",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "Copy of A with the Bth byte set to small integer (between 0..255) C",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 87,
-      "Name": "extract",
-      "Args": "B",
-      "Returns": "B",
-      "Cost": 1,
-      "Size": 3,
-      "Doc": "A range of bytes from A starting at S up to but not including S+L. If L is 0, then extract to the end of the string. If S or S+L is larger than the array length, the program fails",
-      "ImmediateNote": "{uint8 start position} {uint8 length}",
-      "Groups": ["Byte Array Manipulation"]
-    },
-    {
-      "Opcode": 88,
-      "Name": "extract3",
-      "Args": "BUU",
-      "Returns": "B",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "A range of bytes from A starting at B up to but not including B+C. If B+C is larger than the array length, the program fails",
-      "Groups": ["Byte Array Manipulation"]
-    },
-    {
-      "Opcode": 89,
-      "Name": "extract_uint16",
-      "Args": "BU",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "A uint16 formed from a range of big-endian bytes from A starting at B up to but not including B+2. If B+2 is larger than the array length, the program fails",
-      "Groups": ["Byte Array Manipulation"]
-    },
-    {
-      "Opcode": 90,
-      "Name": "extract_uint32",
-      "Args": "BU",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "A uint32 formed from a range of big-endian bytes from A starting at B up to but not including B+4. If B+4 is larger than the array length, the program fails",
-      "Groups": ["Byte Array Manipulation"]
-    },
-    {
-      "Opcode": 91,
-      "Name": "extract_uint64",
-      "Args": "BU",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "A uint64 formed from a range of big-endian bytes from A starting at B up to but not including B+8. If B+8 is larger than the array length, the program fails",
-      "Groups": ["Byte Array Manipulation"]
-    },
-    {
-      "Opcode": 96,
-      "Name": "balance",
-      "Args": ".",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "get balance for account A, in microalgos. The balance is observed after the effects of previous transactions in the group, and after the fee for the current transaction is deducted.",
-      "DocExtra": "params: Txn.Accounts offset (or, since v4, an _available_ account address), _available_ application id (or, since v4, a Txn.ForeignApps offset). Return: value.",
-      "Groups": ["State Access"]
-    },
-    {
-      "Opcode": 97,
-      "Name": "app_opted_in",
-      "Args": ".U",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "1 if account A is opted in to application B, else 0",
-      "DocExtra": "params: Txn.Accounts offset (or, since v4, an _available_ account address), _available_ application id (or, since v4, a Txn.ForeignApps offset). Return: 1 if opted in and 0 otherwise.",
-      "Groups": ["State Access"]
-    },
-    {
-      "Opcode": 98,
-      "Name": "app_local_get",
-      "Args": ".B",
-      "Returns": ".",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "local state of the key B in the current application in account A",
-      "DocExtra": "params: Txn.Accounts offset (or, since v4, an _available_ account address), state key. Return: value. The value is zero (of type uint64) if the key does not exist.",
-      "Groups": ["State Access"]
-    },
-    {
-      "Opcode": 99,
-      "Name": "app_local_get_ex",
-      "Args": ".UB",
-      "Returns": ".U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "X is the local state of application B, key C in account A. Y is 1 if key existed, else 0",
-      "DocExtra": "params: Txn.Accounts offset (or, since v4, an _available_ account address), _available_ application id (or, since v4, a Txn.ForeignApps offset), state key. Return: did_exist flag (top of the stack, 1 if the application and key existed and 0 otherwise), value. The value is zero (of type uint64) if the key does not exist.",
-      "Groups": ["State Access"]
-    },
-    {
-      "Opcode": 100,
-      "Name": "app_global_get",
-      "Args": "B",
-      "Returns": ".",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "global state of the key A in the current application",
-      "DocExtra": "params: state key. Return: value. The value is zero (of type uint64) if the key does not exist.",
-      "Groups": ["State Access"]
-    },
-    {
-      "Opcode": 101,
-      "Name": "app_global_get_ex",
-      "Args": "UB",
-      "Returns": ".U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "X is the global state of application A, key B. Y is 1 if key existed, else 0",
-      "DocExtra": "params: Txn.ForeignApps offset (or, since v4, an _available_ application id), state key. Return: did_exist flag (top of the stack, 1 if the application and key existed and 0 otherwise), value. The value is zero (of type uint64) if the key does not exist.",
-      "Groups": ["State Access"]
-    },
-    {
-      "Opcode": 102,
-      "Name": "app_local_put",
-      "Args": ".B.",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "write C to key B in account A's local state of the current application",
-      "DocExtra": "params: Txn.Accounts offset (or, since v4, an _available_ account address), state key, value.",
-      "Groups": ["State Access"]
-    },
-    {
-      "Opcode": 103,
-      "Name": "app_global_put",
-      "Args": "B.",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "write B to key A in the global state of the current application",
-      "Groups": ["State Access"]
-    },
-    {
-      "Opcode": 104,
-      "Name": "app_local_del",
-      "Args": ".B",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "delete key B from account A's local state of the current application",
-      "DocExtra": "params: Txn.Accounts offset (or, since v4, an _available_ account address), state key.\n\nDeleting a key which is already absent has no effect on the application local state. (In particular, it does _not_ cause the program to fail.)",
-      "Groups": ["State Access"]
-    },
-    {
-      "Opcode": 105,
-      "Name": "app_global_del",
-      "Args": "B",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "delete key A from the global state of the current application",
-      "DocExtra": "params: state key.\n\nDeleting a key which is already absent has no effect on the application global state. (In particular, it does _not_ cause the program to fail.)",
-      "Groups": ["State Access"]
-    },
-    {
-      "Opcode": 112,
-      "Name": "asset_holding_get",
-      "Args": ".U",
-      "Returns": ".U",
-      "Cost": 1,
-      "Size": 2,
-      "ArgEnum": ["AssetBalance", "AssetFrozen"],
-      "ArgEnumTypes": "UU",
-      "Doc": "X is field F from account A's holding of asset B. Y is 1 if A is opted into B, else 0",
-      "DocExtra": "params: Txn.Accounts offset (or, since v4, an _available_ address), asset id (or, since v4, a Txn.ForeignAssets offset). Return: did_exist flag (1 if the asset existed and 0 otherwise), value.",
-      "ImmediateNote": "{uint8 asset holding field index}",
-      "Groups": ["State Access"]
-    },
-    {
-      "Opcode": 113,
-      "Name": "asset_params_get",
-      "Args": "U",
-      "Returns": ".U",
-      "Cost": 1,
-      "Size": 2,
-      "ArgEnum": [
-        "AssetTotal",
-        "AssetDecimals",
-        "AssetDefaultFrozen",
-        "AssetUnitName",
-        "AssetName",
-        "AssetURL",
-        "AssetMetadataHash",
-        "AssetManager",
-        "AssetReserve",
-        "AssetFreeze",
-        "AssetClawback",
-        "AssetCreator"
-      ],
-      "ArgEnumTypes": "UUUBBBBBBBBB",
-      "Doc": "X is field F from asset A. Y is 1 if A exists, else 0",
-      "DocExtra": "params: Txn.ForeignAssets offset (or, since v4, an _available_ asset id. Return: did_exist flag (1 if the asset existed and 0 otherwise), value.",
-      "ImmediateNote": "{uint8 asset params field index}",
-      "Groups": ["State Access"]
-    },
-    {
-      "Opcode": 114,
-      "Name": "app_params_get",
-      "Args": "U",
-      "Returns": ".U",
-      "Cost": 1,
-      "Size": 2,
-      "ArgEnum": [
-        "AppApprovalProgram",
-        "AppClearStateProgram",
-        "AppGlobalNumUint",
-        "AppGlobalNumByteSlice",
-        "AppLocalNumUint",
-        "AppLocalNumByteSlice",
-        "AppExtraProgramPages",
-        "AppCreator",
-        "AppAddress"
-      ],
-      "ArgEnumTypes": "BBUUUUUBB",
-      "Doc": "X is field F from app A. Y is 1 if A exists, else 0",
-      "DocExtra": "params: Txn.ForeignApps offset or an _available_ app id. Return: did_exist flag (1 if the application existed and 0 otherwise), value.",
-      "ImmediateNote": "{uint8 app params field index}",
-      "Groups": ["State Access"]
-    },
-    {
-      "Opcode": 115,
-      "Name": "acct_params_get",
-      "Args": ".",
-      "Returns": ".U",
-      "Cost": 1,
-      "Size": 2,
-      "Doc": "X is field F from account A. Y is 1 if A owns positive algos, else 0",
-      "ImmediateNote": "{uint8 account params field index}",
-      "Groups": ["State Access"]
-    },
-    {
-      "Opcode": 120,
-      "Name": "min_balance",
-      "Args": ".",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "get minimum required balance for account A, in microalgos. Required balance is affected by [ASA](https://developer.algorand.org/docs/features/asa/#assets-overview) and [App](https://developer.algorand.org/docs/features/asc1/stateful/#minimum-balance-requirement-for-a-smart-contract) usage. When creating or opting into an app, the minimum balance grows before the app code runs, therefore the increase is visible there. When deleting or closing out, the minimum balance decreases after the app executes.",
-      "DocExtra": "params: Txn.Accounts offset (or, since v4, an _available_ account address), _available_ application id (or, since v4, a Txn.ForeignApps offset). Return: value.",
-      "Groups": ["State Access"]
-    },
-    {
-      "Opcode": 128,
-      "Name": "pushbytes",
-      "Returns": "B",
-      "Cost": 1,
-      "Size": 0,
-      "Doc": "immediate BYTES",
-      "DocExtra": "pushbytes args are not added to the bytecblock during assembly processes",
-      "ImmediateNote": "{varuint length} {bytes}",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 129,
-      "Name": "pushint",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 0,
-      "Doc": "immediate UINT",
-      "DocExtra": "pushint args are not added to the intcblock during assembly processes",
-      "ImmediateNote": "{varuint int}",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 136,
-      "Name": "callsub",
-      "Cost": 1,
-      "Size": 3,
-      "Doc": "branch unconditionally to TARGET, saving the next instruction on the call stack",
-      "DocExtra": "The call stack is separate from the data stack. Only `callsub` and `retsub` manipulate it.",
-      "ImmediateNote": "{int16 branch offset, big endian}",
-      "Groups": ["Flow Control"]
-    },
-    {
-      "Opcode": 137,
-      "Name": "retsub",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "pop the top instruction from the call stack and branch to it",
-      "DocExtra": "The call stack is separate from the data stack. Only `callsub` and `retsub` manipulate it.",
-      "Groups": ["Flow Control"]
-    },
-    {
-      "Opcode": 144,
-      "Name": "shl",
-      "Args": "UU",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "A times 2^B, modulo 2^64",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 145,
-      "Name": "shr",
-      "Args": "UU",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "A divided by 2^B",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 146,
-      "Name": "sqrt",
-      "Args": "U",
-      "Returns": "U",
-      "Cost": 4,
-      "Size": 1,
-      "Doc": "The largest integer I such that I^2 \u003c= A",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 147,
-      "Name": "bitlen",
-      "Args": ".",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "The highest set bit in A. If A is a byte-array, it is interpreted as a big-endian unsigned integer. bitlen of 0 is 0, bitlen of 8 is 4",
-      "DocExtra": "bitlen interprets arrays as big-endian integers, unlike setbit/getbit",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 148,
-      "Name": "exp",
-      "Args": "UU",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "A raised to the Bth power. Fail if A == B == 0 and on overflow",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 149,
-      "Name": "expw",
-      "Args": "UU",
-      "Returns": "UU",
-      "Cost": 10,
-      "Size": 1,
-      "Doc": "A raised to the Bth power as a 128-bit result in two uint64s. X is the high 64 bits, Y is the low. Fail if A == B == 0 or if the results exceeds 2^128-1",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 150,
-      "Name": "bsqrt",
-      "Args": "B",
-      "Returns": "B",
-      "Cost": 40,
-      "Size": 1,
-      "Doc": "The largest integer I such that I^2 \u003c= A. A and I are interpreted as big-endian unsigned integers",
-      "Groups": ["Byte Array Arithmetic"]
-    },
-    {
-      "Opcode": 151,
-      "Name": "divw",
-      "Args": "UUU",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "A,B / C. Fail if C == 0 or if result overflows.",
-      "DocExtra": "The notation A,B indicates that A and B are interpreted as a uint128 value, with A as the high uint64 and B the low.",
-      "Groups": ["Arithmetic"]
-    },
-    {
-      "Opcode": 160,
-      "Name": "b+",
-      "Args": "BB",
-      "Returns": "B",
-      "Cost": 10,
-      "Size": 1,
-      "Doc": "A plus B. A and B are interpreted as big-endian unsigned integers",
-      "Groups": ["Byte Array Arithmetic"]
-    },
-    {
-      "Opcode": 161,
-      "Name": "b-",
-      "Args": "BB",
-      "Returns": "B",
-      "Cost": 10,
-      "Size": 1,
-      "Doc": "A minus B. A and B are interpreted as big-endian unsigned integers. Fail on underflow.",
-      "Groups": ["Byte Array Arithmetic"]
-    },
-    {
-      "Opcode": 162,
-      "Name": "b/",
-      "Args": "BB",
-      "Returns": "B",
-      "Cost": 20,
-      "Size": 1,
-      "Doc": "A divided by B (truncated division). A and B are interpreted as big-endian unsigned integers. Fail if B is zero.",
-      "Groups": ["Byte Array Arithmetic"]
-    },
-    {
-      "Opcode": 163,
-      "Name": "b*",
-      "Args": "BB",
-      "Returns": "B",
-      "Cost": 20,
-      "Size": 1,
-      "Doc": "A times B. A and B are interpreted as big-endian unsigned integers.",
-      "Groups": ["Byte Array Arithmetic"]
-    },
-    {
-      "Opcode": 164,
-      "Name": "b\u003c",
-      "Args": "BB",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "1 if A is less than B, else 0. A and B are interpreted as big-endian unsigned integers",
-      "Groups": ["Byte Array Arithmetic"]
-    },
-    {
-      "Opcode": 165,
-      "Name": "b\u003e",
-      "Args": "BB",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "1 if A is greater than B, else 0. A and B are interpreted as big-endian unsigned integers",
-      "Groups": ["Byte Array Arithmetic"]
-    },
-    {
-      "Opcode": 166,
-      "Name": "b\u003c=",
-      "Args": "BB",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "1 if A is less than or equal to B, else 0. A and B are interpreted as big-endian unsigned integers",
-      "Groups": ["Byte Array Arithmetic"]
-    },
-    {
-      "Opcode": 167,
-      "Name": "b\u003e=",
-      "Args": "BB",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "1 if A is greater than or equal to B, else 0. A and B are interpreted as big-endian unsigned integers",
-      "Groups": ["Byte Array Arithmetic"]
-    },
-    {
-      "Opcode": 168,
-      "Name": "b==",
-      "Args": "BB",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "1 if A is equal to B, else 0. A and B are interpreted as big-endian unsigned integers",
-      "Groups": ["Byte Array Arithmetic"]
-    },
-    {
-      "Opcode": 169,
-      "Name": "b!=",
-      "Args": "BB",
-      "Returns": "U",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "0 if A is equal to B, else 1. A and B are interpreted as big-endian unsigned integers",
-      "Groups": ["Byte Array Arithmetic"]
-    },
-    {
-      "Opcode": 170,
-      "Name": "b%",
-      "Args": "BB",
-      "Returns": "B",
-      "Cost": 20,
-      "Size": 1,
-      "Doc": "A modulo B. A and B are interpreted as big-endian unsigned integers. Fail if B is zero.",
-      "Groups": ["Byte Array Arithmetic"]
-    },
-    {
-      "Opcode": 171,
-      "Name": "b|",
-      "Args": "BB",
-      "Returns": "B",
-      "Cost": 6,
-      "Size": 1,
-      "Doc": "A bitwise-or B. A and B are zero-left extended to the greater of their lengths",
-      "Groups": ["Byte Array Logic"]
-    },
-    {
-      "Opcode": 172,
-      "Name": "b\u0026",
-      "Args": "BB",
-      "Returns": "B",
-      "Cost": 6,
-      "Size": 1,
-      "Doc": "A bitwise-and B. A and B are zero-left extended to the greater of their lengths",
-      "Groups": ["Byte Array Logic"]
-    },
-    {
-      "Opcode": 173,
-      "Name": "b^",
-      "Args": "BB",
-      "Returns": "B",
-      "Cost": 6,
-      "Size": 1,
-      "Doc": "A bitwise-xor B. A and B are zero-left extended to the greater of their lengths",
-      "Groups": ["Byte Array Logic"]
-    },
-    {
-      "Opcode": 174,
-      "Name": "b~",
-      "Args": "B",
-      "Returns": "B",
-      "Cost": 4,
-      "Size": 1,
-      "Doc": "A with all bits inverted",
-      "Groups": ["Byte Array Logic"]
-    },
-    {
-      "Opcode": 175,
-      "Name": "bzero",
-      "Args": "U",
-      "Returns": "B",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "zero filled byte-array of length A",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 176,
-      "Name": "log",
-      "Args": "B",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "write A to log state of the current application",
-      "DocExtra": "`log` fails if called more than MaxLogCalls times in a program, or if the sum of logged bytes exceeds 1024 bytes.",
-      "Groups": ["State Access"]
-    },
-    {
-      "Opcode": 177,
-      "Name": "itxn_begin",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "begin preparation of a new inner transaction in a new transaction group",
-      "DocExtra": "`itxn_begin` initializes Sender to the application address; Fee to the minimum allowable, taking into account MinTxnFee and credit from overpaying in earlier transactions; FirstValid/LastValid to the values in the invoking transaction, and all other fields to zero or empty values.",
-      "Groups": ["Inner Transactions"]
-    },
-    {
-      "Opcode": 178,
-      "Name": "itxn_field",
-      "Args": ".",
-      "Cost": 1,
-      "Size": 2,
-      "ArgEnum": [
-        "Sender",
-        "Fee",
-        "FirstValid",
-        "FirstValidTime",
-        "LastValid",
-        "Note",
-        "Lease",
-        "Receiver",
-        "Amount",
-        "CloseRemainderTo",
-        "VotePK",
-        "SelectionPK",
-        "VoteFirst",
-        "VoteLast",
-        "VoteKeyDilution",
-        "Type",
-        "TypeEnum",
-        "XferAsset",
-        "AssetAmount",
-        "AssetSender",
-        "AssetReceiver",
-        "AssetCloseTo",
-        "GroupIndex",
-        "TxID",
-        "ApplicationID",
-        "OnCompletion",
-        "ApplicationArgs",
-        "NumAppArgs",
-        "Accounts",
-        "NumAccounts",
-        "ApprovalProgram",
-        "ClearStateProgram",
-        "RekeyTo",
-        "ConfigAsset",
-        "ConfigAssetTotal",
-        "ConfigAssetDecimals",
-        "ConfigAssetDefaultFrozen",
-        "ConfigAssetUnitName",
-        "ConfigAssetName",
-        "ConfigAssetURL",
-        "ConfigAssetMetadataHash",
-        "ConfigAssetManager",
-        "ConfigAssetReserve",
-        "ConfigAssetFreeze",
-        "ConfigAssetClawback",
-        "FreezeAsset",
-        "FreezeAssetAccount",
-        "FreezeAssetFrozen",
-        "Assets",
-        "NumAssets",
-        "Applications",
-        "NumApplications",
-        "GlobalNumUint",
-        "GlobalNumByteSlice",
-        "LocalNumUint",
-        "LocalNumByteSlice",
-        "ExtraProgramPages",
-        "Nonparticipation",
-        "Logs",
-        "NumLogs",
-        "CreatedAssetID",
-        "CreatedApplicationID",
-        "LastLog",
-        "StateProofPK"
-      ],
-      "ArgEnumTypes": "BUUUUBBBUBBBUUUBUUUBBBUBUUBUBUBBBUUUUBBBBBBBBUBUUUUUUUUUUUBUUUBB",
-      "Doc": "set field F of the current inner transaction to A",
-      "DocExtra": "`itxn_field` fails if A is of the wrong type for F, including a byte array of the wrong size for use as an address when F is an address field. `itxn_field` also fails if A is an account, asset, or app that is not _available_, or an attempt is made extend an array field beyond the limit imposed by consensus parameters. (Addresses set into asset params of acfg transactions need not be _available_.)",
-      "ImmediateNote": "{uint8 transaction field index}",
-      "Groups": ["Inner Transactions"]
-    },
-    {
-      "Opcode": 179,
-      "Name": "itxn_submit",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "execute the current inner transaction group. Fail if executing this group would exceed the inner transaction limit, or if any transaction in the group fails.",
-      "DocExtra": "`itxn_submit` resets the current transaction so that it can not be resubmitted. A new `itxn_begin` is required to prepare another inner transaction.",
-      "Groups": ["Inner Transactions"]
-    },
-    {
-      "Opcode": 180,
-      "Name": "itxn",
-      "Returns": ".",
-      "Cost": 1,
-      "Size": 2,
-      "ArgEnum": [
-        "Sender",
-        "Fee",
-        "FirstValid",
-        "FirstValidTime",
-        "LastValid",
-        "Note",
-        "Lease",
-        "Receiver",
-        "Amount",
-        "CloseRemainderTo",
-        "VotePK",
-        "SelectionPK",
-        "VoteFirst",
-        "VoteLast",
-        "VoteKeyDilution",
-        "Type",
-        "TypeEnum",
-        "XferAsset",
-        "AssetAmount",
-        "AssetSender",
-        "AssetReceiver",
-        "AssetCloseTo",
-        "GroupIndex",
-        "TxID",
-        "ApplicationID",
-        "OnCompletion",
-        "ApplicationArgs",
-        "NumAppArgs",
-        "Accounts",
-        "NumAccounts",
-        "ApprovalProgram",
-        "ClearStateProgram",
-        "RekeyTo",
-        "ConfigAsset",
-        "ConfigAssetTotal",
-        "ConfigAssetDecimals",
-        "ConfigAssetDefaultFrozen",
-        "ConfigAssetUnitName",
-        "ConfigAssetName",
-        "ConfigAssetURL",
-        "ConfigAssetMetadataHash",
-        "ConfigAssetManager",
-        "ConfigAssetReserve",
-        "ConfigAssetFreeze",
-        "ConfigAssetClawback",
-        "FreezeAsset",
-        "FreezeAssetAccount",
-        "FreezeAssetFrozen",
-        "Assets",
-        "NumAssets",
-        "Applications",
-        "NumApplications",
-        "GlobalNumUint",
-        "GlobalNumByteSlice",
-        "LocalNumUint",
-        "LocalNumByteSlice",
-        "ExtraProgramPages",
-        "Nonparticipation",
-        "Logs",
-        "NumLogs",
-        "CreatedAssetID",
-        "CreatedApplicationID",
-        "LastLog",
-        "StateProofPK"
-      ],
-      "ArgEnumTypes": "BUUUUBBBUBBBUUUBUUUBBBUBUUBUBUBBBUUUUBBBBBBBBUBUUUUUUUUUUUBUUUBB",
-      "Doc": "field F of the last inner transaction",
-      "ImmediateNote": "{uint8 transaction field index}",
-      "Groups": ["Inner Transactions"]
-    },
-    {
-      "Opcode": 181,
-      "Name": "itxna",
-      "Returns": ".",
-      "Cost": 1,
-      "Size": 3,
-      "ArgEnum": [
-        "ApplicationArgs",
-        "Accounts",
-        "Assets",
-        "Applications",
-        "Logs"
-      ],
-      "ArgEnumTypes": "BBUUB",
-      "Doc": "Ith value of the array field F of the last inner transaction",
-      "ImmediateNote": "{uint8 transaction field index} {uint8 transaction field array index}",
-      "Groups": ["Inner Transactions"]
-    },
-    {
-      "Opcode": 182,
-      "Name": "itxn_next",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "begin preparation of a new inner transaction in the same transaction group",
-      "DocExtra": "`itxn_next` initializes the transaction exactly as `itxn_begin` does",
-      "Groups": ["Inner Transactions"]
-    },
-    {
-      "Opcode": 183,
-      "Name": "gitxn",
-      "Returns": ".",
-      "Cost": 1,
-      "Size": 3,
-      "ArgEnum": [
-        "Sender",
-        "Fee",
-        "FirstValid",
-        "FirstValidTime",
-        "LastValid",
-        "Note",
-        "Lease",
-        "Receiver",
-        "Amount",
-        "CloseRemainderTo",
-        "VotePK",
-        "SelectionPK",
-        "VoteFirst",
-        "VoteLast",
-        "VoteKeyDilution",
-        "Type",
-        "TypeEnum",
-        "XferAsset",
-        "AssetAmount",
-        "AssetSender",
-        "AssetReceiver",
-        "AssetCloseTo",
-        "GroupIndex",
-        "TxID",
-        "ApplicationID",
-        "OnCompletion",
-        "ApplicationArgs",
-        "NumAppArgs",
-        "Accounts",
-        "NumAccounts",
-        "ApprovalProgram",
-        "ClearStateProgram",
-        "RekeyTo",
-        "ConfigAsset",
-        "ConfigAssetTotal",
-        "ConfigAssetDecimals",
-        "ConfigAssetDefaultFrozen",
-        "ConfigAssetUnitName",
-        "ConfigAssetName",
-        "ConfigAssetURL",
-        "ConfigAssetMetadataHash",
-        "ConfigAssetManager",
-        "ConfigAssetReserve",
-        "ConfigAssetFreeze",
-        "ConfigAssetClawback",
-        "FreezeAsset",
-        "FreezeAssetAccount",
-        "FreezeAssetFrozen",
-        "Assets",
-        "NumAssets",
-        "Applications",
-        "NumApplications",
-        "GlobalNumUint",
-        "GlobalNumByteSlice",
-        "LocalNumUint",
-        "LocalNumByteSlice",
-        "ExtraProgramPages",
-        "Nonparticipation",
-        "Logs",
-        "NumLogs",
-        "CreatedAssetID",
-        "CreatedApplicationID",
-        "LastLog",
-        "StateProofPK"
-      ],
-      "ArgEnumTypes": "BUUUUBBBUBBBUUUBUUUBBBUBUUBUBUBBBUUUUBBBBBBBBUBUUUUUUUUUUUBUUUBB",
-      "Doc": "field F of the Tth transaction in the last inner group submitted",
-      "ImmediateNote": "{uint8 transaction group index} {uint8 transaction field index}",
-      "Groups": ["Inner Transactions"]
-    },
-    {
-      "Opcode": 184,
-      "Name": "gitxna",
-      "Returns": ".",
-      "Cost": 1,
-      "Size": 4,
-      "ArgEnum": [
-        "ApplicationArgs",
-        "Accounts",
-        "Assets",
-        "Applications",
-        "Logs"
-      ],
-      "ArgEnumTypes": "BBUUB",
-      "Doc": "Ith value of the array field F from the Tth transaction in the last inner group submitted",
-      "ImmediateNote": "{uint8 transaction group index} {uint8 transaction field index} {uint8 transaction field array index}",
-      "Groups": ["Inner Transactions"]
-    },
-    {
-      "Opcode": 192,
-      "Name": "txnas",
-      "Args": "U",
-      "Returns": ".",
-      "Cost": 1,
-      "Size": 2,
-      "ArgEnum": [
-        "ApplicationArgs",
-        "Accounts",
-        "Assets",
-        "Applications",
-        "Logs"
-      ],
-      "ArgEnumTypes": "BBUUB",
-      "Doc": "Ath value of the array field F of the current transaction",
-      "ImmediateNote": "{uint8 transaction field index}",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 193,
-      "Name": "gtxnas",
-      "Args": "U",
-      "Returns": ".",
-      "Cost": 1,
-      "Size": 3,
-      "ArgEnum": [
-        "ApplicationArgs",
-        "Accounts",
-        "Assets",
-        "Applications",
-        "Logs"
-      ],
-      "ArgEnumTypes": "BBUUB",
-      "Doc": "Ath value of the array field F from the Tth transaction in the current group",
-      "ImmediateNote": "{uint8 transaction group index} {uint8 transaction field index}",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 194,
-      "Name": "gtxnsas",
-      "Args": "UU",
-      "Returns": ".",
-      "Cost": 1,
-      "Size": 2,
-      "ArgEnum": [
-        "ApplicationArgs",
-        "Accounts",
-        "Assets",
-        "Applications",
-        "Logs"
-      ],
-      "ArgEnumTypes": "BBUUB",
-      "Doc": "Bth value of the array field F from the Ath transaction in the current group",
-      "ImmediateNote": "{uint8 transaction field index}",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 195,
-      "Name": "args",
-      "Args": "U",
-      "Returns": "B",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "Ath LogicSig argument",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 196,
-      "Name": "gloadss",
-      "Args": "UU",
-      "Returns": ".",
-      "Cost": 1,
-      "Size": 1,
-      "Doc": "Bth scratch space value of the Ath transaction in the current group",
-      "Groups": ["Loading Values"]
-    },
-    {
-      "Opcode": 197,
-      "Name": "itxnas",
-      "Args": "U",
-      "Returns": ".",
-      "Cost": 1,
-      "Size": 2,
-      "Doc": "Ath value of the array field F of the last inner transaction",
-      "ImmediateNote": "{uint8 transaction field index}",
-      "Groups": ["Inner Transactions"]
-    },
-    {
-      "Opcode": 198,
-      "Name": "gitxnas",
-      "Args": "U",
-      "Returns": ".",
-      "Cost": 1,
-      "Size": 3,
-      "Doc": "Ath value of the array field F from the Tth transaction in the last inner group submitted",
-      "ImmediateNote": "{uint8 transaction group index} {uint8 transaction field index}",
-      "Groups": ["Inner Transactions"]
-    }
-  ]
-}
diff --git a/src/logic/logic.ts b/src/logic/logic.ts
deleted file mode 100644
index f425329..0000000
--- a/src/logic/logic.ts
+++ /dev/null
@@ -1,316 +0,0 @@
-/* eslint-disable no-bitwise */
-/**
- * Utilities for working with program bytes.
- */
-
-/** @deprecated langspec.json is deprecated aross all SDKs */
-import langspec from './langspec.json';
-
-/**
- * Langspec Op Structure
- * @deprecated for langspec.json is deprecated aross all SDKs
- */
-interface OpStructure {
-  Opcode: number;
-  Name: string;
-  Args?: string;
-  Returns?: string;
-  Cost: number;
-  Size: number;
-  ArgEnum?: string[];
-  ArgEnumTypes?: string;
-  Doc: string;
-  DocExtra?: string;
-  ImmediateNote?: string;
-  Groups: string[];
-}
-
-/** @deprecated for langspec.json is deprecated aross all SDKs */
-let opcodes: {
-  [key: number]: OpStructure;
-};
-
-/** @deprecated for langspec.json is deprecated aross all SDKs */
-const maxCost = 20000;
-/** @deprecated for langspec.json is deprecated aross all SDKs */
-const maxLength = 1000;
-
-/** @deprecated for langspec.json is deprecated aross all SDKs */
-export function parseUvarint(
-  array: Uint8Array
-): [numberFound: number, size: number] {
-  let x = 0;
-  let s = 0;
-  for (let i = 0; i < array.length; i++) {
-    const b = array[i];
-    if (b < 0x80) {
-      if (i > 9 || (i === 9 && b > 1)) {
-        return [0, -(i + 1)];
-      }
-      return [x | (b << s), i + 1];
-    }
-    x += (b & 0x7f) << s;
-    s += 7;
-  }
-  return [0, 0];
-}
-
-/** @deprecated for langspec.json is deprecated aross all SDKs */
-function readIntConstBlock(
-  program: Uint8Array,
-  pc: number
-): [size: number, ints: number[]] {
-  let size = 1;
-  const parsed = parseUvarint(program.slice(pc + size));
-  const numInts = parsed[0];
-  let bytesUsed = parsed[1];
-  if (bytesUsed <= 0) {
-    throw new Error(`could not decode int const block size at pc=${pc + size}`);
-  }
-  const ints: number[] = [];
-  size += bytesUsed;
-  for (let i = 0; i < numInts; i++) {
-    if (pc + size >= program.length) {
-      throw new Error('intcblock ran past end of program');
-    }
-    let numberFound: number;
-    [numberFound, bytesUsed] = parseUvarint(program.slice(pc + size));
-    if (bytesUsed <= 0) {
-      throw new Error(
-        `could not decode int const[${i}] block size at pc=${pc + size}`
-      );
-    }
-    ints.push(numberFound);
-    size += bytesUsed;
-  }
-  return [size, ints];
-}
-
-/** @deprecated for langspec.json is deprecated aross all SDKs */
-function readByteConstBlock(
-  program: Uint8Array,
-  pc: number
-): [size: number, byteArrays: Uint8Array[]] {
-  let size = 1;
-  const parsed = parseUvarint(program.slice(pc + size));
-  const numInts = parsed[0];
-  let bytesUsed = parsed[1];
-  if (bytesUsed <= 0) {
-    throw new Error(
-      `could not decode []byte const block size at pc=${pc + size}`
-    );
-  }
-  const byteArrays: Uint8Array[] = [];
-  size += bytesUsed;
-  for (let i = 0; i < numInts; i++) {
-    if (pc + size >= program.length) {
-      throw new Error('bytecblock ran past end of program');
-    }
-    let itemLen: number;
-    [itemLen, bytesUsed] = parseUvarint(program.slice(pc + size));
-    if (bytesUsed <= 0) {
-      throw new Error(
-        `could not decode []byte] const[${i}] block size at pc=${pc + size}`
-      );
-    }
-    size += bytesUsed;
-    if (pc + size + itemLen > program.length) {
-      throw new Error('bytecblock ran past end of program');
-    }
-    const byteArray = program.slice(pc + size, pc + size + itemLen);
-    byteArrays.push(byteArray);
-    size += itemLen;
-  }
-  return [size, byteArrays];
-}
-
-/** @deprecated for langspec.json is deprecated aross all SDKs */
-function readPushIntOp(
-  program: Uint8Array,
-  pc: number
-): [size: number, numberFound: number] {
-  let size = 1;
-  const [numberFound, bytesUsed] = parseUvarint(program.slice(pc + size));
-  if (bytesUsed <= 0) {
-    throw new Error(`could not decode push int const at pc=${pc + size}`);
-  }
-  size += bytesUsed;
-  return [size, numberFound];
-}
-
-/** @deprecated for langspec.json is deprecated aross all SDKs */
-function readPushByteOp(
-  program: Uint8Array,
-  pc: number
-): [size: number, byteArray: Uint8Array] {
-  let size = 1;
-  const [itemLen, bytesUsed] = parseUvarint(program.slice(pc + size));
-  if (bytesUsed <= 0) {
-    throw new Error(
-      `could not decode push []byte const size at pc=${pc + size}`
-    );
-  }
-  size += bytesUsed;
-  if (pc + size + itemLen > program.length) {
-    throw new Error('pushbytes ran past end of program');
-  }
-  const byteArray = program.slice(pc + size, pc + size + itemLen);
-  size += itemLen;
-  return [size, byteArray];
-}
-
-/** readProgram validates program for length and running cost,
- * and additionally provides the found int variables and byte blocks
- *
- * @deprecated Validation relies on metadata (`langspec.json`) that
- * does not accurately represent opcode behavior across program versions.
- * The behavior of `readProgram` relies on `langspec.json`.
- * Thus, this method is being deprecated.
- *
- * @param program - Program to check
- * @param args - Program arguments as array of Uint8Array arrays
- * @throws
- * @returns
- */
-export function readProgram(
-  program: Uint8Array,
-  args?: Uint8Array[]
-): [ints: number[], byteArrays: Uint8Array[], valid: boolean] {
-  const intcblockOpcode = 32;
-  const bytecblockOpcode = 38;
-  const pushbytesOpcode = 128;
-  const pushintOpcode = 129;
-
-  if (!program) {
-    throw new Error('empty program');
-  }
-
-  if (typeof args === 'undefined') {
-    // eslint-disable-next-line no-param-reassign
-    args = [];
-  }
-  if (!Array.isArray(args)) {
-    throw new Error('invalid arguments');
-  }
-
-  const [version, vlen] = parseUvarint(program);
-  if (vlen <= 0) {
-    throw new Error('version parsing error');
-  }
-  if (version > langspec.EvalMaxVersion) {
-    throw new Error('unsupported version');
-  }
-
-  let cost = 0;
-  let { length } = program;
-  for (const arg of args) {
-    length += arg.length;
-  }
-  if (length > maxLength) {
-    throw new Error('program too long');
-  }
-
-  if (!opcodes) {
-    opcodes = {};
-    for (const op of langspec.Ops) {
-      opcodes[op.Opcode] = op;
-    }
-  }
-
-  let pc = vlen;
-  let ints: number[] = [];
-  let byteArrays: Uint8Array[] = [];
-  while (pc < program.length) {
-    const op = opcodes[program[pc]];
-    if (op === undefined) {
-      throw new Error('invalid instruction');
-    }
-
-    cost += op.Cost;
-    let size = op.Size;
-    if (size === 0) {
-      switch (op.Opcode) {
-        case intcblockOpcode: {
-          let foundInts: number[];
-          [size, foundInts] = readIntConstBlock(program, pc);
-          ints = ints.concat(foundInts);
-          break;
-        }
-        case bytecblockOpcode: {
-          let foundByteArrays: Uint8Array[];
-          [size, foundByteArrays] = readByteConstBlock(program, pc);
-          byteArrays = byteArrays.concat(foundByteArrays);
-          break;
-        }
-        case pushintOpcode: {
-          let foundInt: number;
-          [size, foundInt] = readPushIntOp(program, pc);
-          ints.push(foundInt);
-          break;
-        }
-        case pushbytesOpcode: {
-          let foundByteArray;
-          [size, foundByteArray] = readPushByteOp(program, pc);
-          byteArrays.push(foundByteArray);
-          break;
-        }
-        default: {
-          throw new Error('invalid instruction');
-        }
-      }
-    }
-    pc += size;
-  }
-  // costs calculated dynamically starting in v4
-  if (version < 4 && cost > maxCost) {
-    throw new Error('program too costly for version < 4. consider using v4.');
-  }
-  return [ints, byteArrays, true];
-}
-
-/**
- * checkProgram validates program for length and running cost
- *
- * @deprecated Validation relies on metadata (`langspec.json`) that
- * does not accurately represent opcode behavior across program versions.
- * The behavior of `checkProgram` relies on `langspec.json`.
- * Thus, this method is being deprecated.
- *
- * @param program - Program to check
- * @param args - Program arguments as array of Uint8Array arrays
- * @throws
- * @returns true if success
- */
-export function checkProgram(program: Uint8Array, args?: Uint8Array[]) {
-  const [, , success] = readProgram(program, args);
-  return success;
-}
-
-/** @deprecated for langspec.json is deprecated aross all SDKs */
-export function checkIntConstBlock(program: Uint8Array, pc: number) {
-  const [size] = readIntConstBlock(program, pc);
-  return size;
-}
-
-/** @deprecated for langspec.json is deprecated aross all SDKs */
-export function checkByteConstBlock(program: Uint8Array, pc: number) {
-  const [size] = readByteConstBlock(program, pc);
-  return size;
-}
-
-/** @deprecated for langspec.json is deprecated aross all SDKs */
-export function checkPushIntOp(program: Uint8Array, pc: number) {
-  const [size] = readPushIntOp(program, pc);
-  return size;
-}
-
-/** @deprecated for langspec.json is deprecated aross all SDKs */
-export function checkPushByteOp(program: Uint8Array, pc: number) {
-  const [size] = readPushByteOp(program, pc);
-  return size;
-}
-
-/** @deprecated for langspec.json is deprecated aross all SDKs */
-export const langspecEvalMaxVersion = langspec.EvalMaxVersion;
-/** @deprecated for langspec.json is deprecated aross all SDKs */
-export const langspecLogicSigVersion = langspec.LogicSigVersion;
diff --git a/src/logicTemplates/dynamicfee.js b/src/logicTemplates/dynamicfee.js
deleted file mode 100644
index 0f71e01..0000000
--- a/src/logicTemplates/dynamicfee.js
+++ /dev/null
@@ -1,219 +0,0 @@
-const address = require('../encoding/address');
-const encoding = require('../encoding/encoding');
-const group = require('../group');
-const logic = require('../logic/logic');
-const logicSig = require('../logicsig');
-const nacl = require('../nacl/naclWrappers');
-const templates = require('./templates');
-const transaction = require('../transaction');
-
-class DynamicFee {
-  /**
-   * DynamicFee contract allows you to create a transaction without
-   * specifying the fee. The fee will be determined at the moment of
-   * transfer.
-   *
-   * @deprecated This feature will be removed in v2.
-   *
-   * Constructor Parameters:
-   * @param {string} receiver: address to receive the assets
-   * @param {int} amount: amount of assets to transfer
-   * @param {int} firstValid: first valid round for the transaction
-   * @param {int} lastValid:  last valid round for the transaction
-   * @param {string} closeRemainder: if you would like to close the account after the transfer, specify the address that would recieve the remainder, else leave undefined
-   * @param {string} lease: leave undefined to generate a random lease, or supply a lease as base64
-   * @returns {DynamicFee}
-   */
-  constructor(receiver, amount, firstValid, lastValid, closeRemainder, lease) {
-    // don't need to validate receiver, closeremainderto - insert will handle that
-    if (!Number.isSafeInteger(amount) || amount < 0)
-      throw Error('amount must be a positive number and smaller than 2^53-1');
-    if (!Number.isSafeInteger(firstValid) || firstValid < 0)
-      throw Error(
-        'firstValid must be a positive number and smaller than 2^53-1'
-      );
-    if (!Number.isSafeInteger(lastValid) || lastValid < 0)
-      throw Error(
-        'lastValid must be a positive number and smaller than 2^53-1'
-      );
-
-    if (typeof closeRemainder === 'undefined') {
-      // eslint-disable-next-line no-param-reassign
-      closeRemainder = address.ALGORAND_ZERO_ADDRESS_STRING;
-    }
-    if (typeof lease === 'undefined') {
-      const leaseBytes = nacl.randomBytes(32);
-      // eslint-disable-next-line no-param-reassign
-      lease = Buffer.from(leaseBytes).toString('base64');
-    }
-
-    const referenceProgramB64 =
-      'ASAFAgEHBgUmAyD+vKC7FEpaTqe0OKRoGsgObKEFvLYH/FZTJclWlfaiEyDmmpYeby1feshmB5JlUr6YI17TM2PKiJGLuck4qRW2+SB/g7Flf/H8U7ktwYFIodZd/C1LH6PWdyhK3dIAEm2QaTIEIhIzABAjEhAzAAcxABIQMwAIMQESEDEWIxIQMRAjEhAxBygSEDEJKRIQMQgkEhAxAiUSEDEEIQQSEDEGKhIQ';
-    const referenceProgramBytes = Buffer.from(referenceProgramB64, 'base64');
-    const referenceOffsets = [
-      5 /* firstValid */,
-      6 /* lastValid */,
-      7 /* receiver */,
-      11 /* closeRemainder */,
-      44 /* lease */,
-      76,
-    ];
-    const injectionVector = [
-      amount,
-      firstValid,
-      lastValid,
-      receiver,
-      closeRemainder,
-      lease,
-    ];
-    const injectionTypes = [
-      templates.valTypes.INT,
-      templates.valTypes.INT,
-      templates.valTypes.INT,
-      templates.valTypes.ADDRESS,
-      templates.valTypes.ADDRESS,
-      templates.valTypes.BASE64,
-    ];
-    const injectedBytes = templates.inject(
-      referenceProgramBytes,
-      referenceOffsets,
-      injectionVector,
-      injectionTypes
-    );
-    this.programBytes = injectedBytes;
-    const lsig = new logicSig.LogicSig(injectedBytes, undefined);
-    this.address = lsig.address();
-  }
-
-  /**
-   * returns the program bytes
-   * @returns {Uint8Array}
-   */
-  getProgram() {
-    return this.programBytes;
-  }
-
-  /**
-   * returns the string address of the contract
-   * @returns {string}
-   */
-  getAddress() {
-    return this.address;
-  }
-}
-/**
- * signDynamicFee returns the main transaction and signed logic needed to complete the transfer.
- * These should be sent to the fee payer, who can use GetDynamicFeeTransactions
- *
- * @deprecated This feature will be removed in v2.
- *
- * @param {Uint8Array} contract: the bytearray representing the contract
- * @param {Uint8Array} secretKey: the secret key for building the logic sig
- * @param {string} genesisHash: the genesisHash to use for the txn
- * @returns {Object} object containing json of txnbuilder constructor arguments under "txn" and signed logicsig under "lsig"
- */
-function signDynamicFee(contract, secretKey, genesisHash) {
-  const programOutputs = logic.readProgram(contract, undefined);
-  const ints = programOutputs[0];
-  const byteArrays = programOutputs[1];
-  const keys = nacl.keyPairFromSecretKey(secretKey);
-  const from = address.encodeAddress(keys.publicKey);
-  const to = address.encodeAddress(byteArrays[0]);
-  const fee = 0;
-  const amount = ints[2];
-  const closeRemainderTo = address.encodeAddress(byteArrays[1]);
-  const firstRound = ints[3];
-  const lastRound = ints[4];
-  const lease = new Uint8Array(byteArrays[2]);
-  const txn = {
-    from,
-    to,
-    fee,
-    amount,
-    closeRemainderTo,
-    firstRound,
-    lastRound,
-    genesisHash,
-    type: 'pay',
-    lease,
-  };
-
-  const lsig = new logicSig.LogicSig(contract, undefined);
-  lsig.sign(secretKey);
-  return { txn, lsig };
-}
-
-/**
- * getDynamicFeeTransactions creates and signs the secondary dynamic fee transaction, updates
- * transaction fields, and signs as the fee payer; it returns both
- * transactions as bytes suitable for sendRaw.
- *
- * @deprecated This feature will be removed in v2.
- *
- * Parameters:
- * @param {dict} txn - main transaction from payer's signDynamicFee output (a dict of constructor arguments, NOT a transaction.Transaction)
- * @param {LogicSig} lsig - the signed logic received from the payer's signDynamicFee output
- * @param {Uint8Array} privateKey - the private key for the account that pays the fee
- * @param {int} fee - fee per byte for both transactions
- *
- * @throws on invalid lsig
- */
-/* eslint-disable no-param-reassign */
-function getDynamicFeeTransactions(txn, lsig, privateKey, fee) {
-  if (!lsig.verify(address.decodeAddress(txn.from).publicKey)) {
-    throw new Error('invalid signature');
-  }
-
-  txn.fee = fee;
-  if (txn.fee < transaction.ALGORAND_MIN_TX_FEE) {
-    txn.fee = transaction.ALGORAND_MIN_TX_FEE;
-  }
-
-  const keys = nacl.keyPairFromSecretKey(privateKey);
-  const from = address.encodeAddress(keys.publicKey);
-
-  // must remove lease and re-add using addLease so that fee calculation will match other SDKs
-  const { lease } = txn;
-  delete txn.lease;
-
-  const txnObj = new transaction.Transaction(txn);
-  txnObj.addLease(lease, fee);
-
-  const feePayTxn = {
-    from,
-    to: txn.from,
-    fee,
-    amount: txnObj.fee, // calculated after txnObj is built to have the correct fee
-    firstRound: txn.firstRound,
-    lastRound: txn.lastRound,
-    genesisHash: txn.genesisHash,
-    type: 'pay',
-  };
-  const feePayTxnObj = new transaction.Transaction(feePayTxn);
-  feePayTxnObj.addLease(lease, fee);
-
-  const txnGroup = group.assignGroupID([feePayTxnObj, txnObj], undefined);
-  const feePayTxnWithGroup = txnGroup[0];
-  const txnObjWithGroup = txnGroup[1];
-
-  const lstx = {
-    lsig: lsig.get_obj_for_encoding(),
-    txn: txnObjWithGroup.get_obj_for_encoding(),
-  };
-
-  const stx1 = feePayTxnWithGroup.signTxn(privateKey);
-  const stx2 = encoding.encode(lstx);
-
-  const concatStx = new Uint8Array(stx1.length + stx2.length);
-  concatStx.set(stx1);
-  concatStx.set(stx2, stx1.length);
-
-  return concatStx;
-}
-/* eslint-enable no-param-reassign */
-
-module.exports = {
-  DynamicFee,
-  getDynamicFeeTransactions,
-  signDynamicFee,
-};
diff --git a/src/logicTemplates/htlc.js b/src/logicTemplates/htlc.js
deleted file mode 100644
index bef0b60..0000000
--- a/src/logicTemplates/htlc.js
+++ /dev/null
@@ -1,165 +0,0 @@
-const sha256 = require('js-sha256');
-const { keccak256 } = require('js-sha3');
-const logic = require('../logic/logic');
-const logicSig = require('../logicsig');
-const templates = require('./templates');
-const transaction = require('../transaction');
-
-class HTLC {
-  /**
-   * HTLC allows a user to receive the Algo prior to a deadline (in terms of a round) by proving a knowledge
-   * of a special value or to forfeit the ability to claim, returning it to the payer.
-   * This contract is usually used to perform cross-chained atomic swaps
-   *
-   * More formally -
-   * Algos can be transferred under only two circumstances:
-   * 1. To receiver if hash_function(arg_0) = hash_value
-   * 2. To owner if txn.FirstValid > expiry_round
-   * ...
-   *
-   * @deprecated This feature will be removed in v2.
-   *
-   *Parameters
-   *----------
-   * @param {string} owner: an address that can receive the asset after the expiry round
-   * @param {string} receiver: address to receive Algos
-   * @param {string} hashFunction: the hash function to be used (must be either sha256 or keccak256)
-   * @param {string} hashImage: the hash image in base64
-   * @param {int} expiryRound: the round on which the assets can be transferred back to owner
-   * @param {int} maxFee: the maximum fee that can be paid to the network by the account
-   * @returns {HTLC}
-   */
-  constructor(owner, receiver, hashFunction, hashImage, expiryRound, maxFee) {
-    // don't need to validate owner, receiver - they'll be validated by template.insert
-    if (!Number.isSafeInteger(expiryRound) || expiryRound < 0)
-      throw Error(
-        'expiryRound must be a positive number and smaller than 2^53-1'
-      );
-    if (!Number.isSafeInteger(maxFee) || maxFee < 0)
-      throw Error('maxFee must be a positive number and smaller than 2^53-1');
-
-    let referenceProgramB64 = '';
-    if (hashFunction === 'sha256') {
-      referenceProgramB64 =
-        'ASAECAEACSYDIOaalh5vLV96yGYHkmVSvpgjXtMzY8qIkYu5yTipFbb5IH+DsWV/8fxTuS3BgUih1l38LUsfo9Z3KErd0gASbZBpIP68oLsUSlpOp7Q4pGgayA5soQW8tgf8VlMlyVaV9qITMQEiDjEQIxIQMQcyAxIQMQgkEhAxCSgSLQEpEhAxCSoSMQIlDRAREA==';
-    } else if (hashFunction === 'keccak256') {
-      referenceProgramB64 =
-        'ASAECAEACSYDIOaalh5vLV96yGYHkmVSvpgjXtMzY8qIkYu5yTipFbb5IH+DsWV/8fxTuS3BgUih1l38LUsfo9Z3KErd0gASbZBpIP68oLsUSlpOp7Q4pGgayA5soQW8tgf8VlMlyVaV9qITMQEiDjEQIxIQMQcyAxIQMQgkEhAxCSgSLQIpEhAxCSoSMQIlDRAREA==';
-    } else {
-      throw Error('hash function unrecognized');
-    }
-    // validate hashImage length
-    const hashImageBytes = Buffer.from(hashImage, 'base64');
-    if (hashImageBytes.length !== 32)
-      throw Error('hash image must be 32 bytes');
-
-    const referenceProgramBytes = Buffer.from(referenceProgramB64, 'base64');
-    const referenceOffsets = [
-      3 /* expiryRound */,
-      6 /* receiver */,
-      10 /* hashImage */,
-      42 /* owner */,
-      76,
-    ];
-    const injectionVector = [maxFee, expiryRound, receiver, hashImage, owner];
-    const injectionTypes = [
-      templates.valTypes.INT,
-      templates.valTypes.INT,
-      templates.valTypes.ADDRESS,
-      templates.valTypes.BASE64,
-      templates.valTypes.ADDRESS,
-    ];
-    const injectedBytes = templates.inject(
-      referenceProgramBytes,
-      referenceOffsets,
-      injectionVector,
-      injectionTypes
-    );
-    this.programBytes = injectedBytes;
-    const lsig = new logicSig.LogicSig(injectedBytes, undefined);
-    this.address = lsig.address();
-  }
-
-  /**
-   * returns the program bytes
-   * @returns {Uint8Array}
-   */
-  getProgram() {
-    return this.programBytes;
-  }
-
-  /**
-   * returns the string address of the contract
-   * @returns {string}
-   */
-  getAddress() {
-    return this.address;
-  }
-}
-
-/**
- *  signTransactionWithHTLCUnlock accepts a transaction, such as a payment, and builds the HTLC-unlocking signature around that transaction
- *
- * @deprecated This feature will be removed in v2.
- *
- * @param {Uint8Array} contract : byte representation of the HTLC
- * @param {Object} txn dictionary containing constructor arguments for a transaction
- * @param {string} preImageAsBase64 : preimage of the hash as base64 string
- *
- * @returns {Object} Object containing txID and blob representing signed transaction.
- * @throws error on validation failure
- */
-function signTransactionWithHTLCUnlock(contract, txn, preImageAsBase64) {
-  const preImageBytes = Buffer.from(preImageAsBase64, 'base64');
-
-  // hash validation
-  const readResult = logic.readProgram(contract, undefined);
-  const ints = readResult[0];
-  const byteArrays = readResult[1];
-  const expectedHashedOutput = byteArrays[1];
-  const hashFunction = contract[contract.length - 15];
-  if (hashFunction === 1) {
-    const hash = sha256.create();
-    hash.update(preImageBytes);
-    const actualHashedOutput = Buffer.from(hash.hex(), 'hex');
-    if (!actualHashedOutput.equals(expectedHashedOutput)) {
-      throw new Error(
-        'sha256 hash of preimage did not match stored contract hash'
-      );
-    }
-  } else if (hashFunction === 2) {
-    const hash = keccak256.create();
-    hash.update(preImageBytes);
-    const actualHashedOutput = Buffer.from(hash.hex(), 'hex');
-    if (!actualHashedOutput.equals(expectedHashedOutput)) {
-      throw new Error(
-        'keccak256 hash of preimage did not match stored contract hash'
-      );
-    }
-  } else {
-    throw new Error('hash function in contract unrecognized');
-  }
-
-  const args = [preImageBytes]; // array of one element, the Uint8Array preimage
-
-  const lsig = new logicSig.LogicSig(contract, args);
-  // clear out receiver just in case
-  // eslint-disable-next-line no-param-reassign
-  delete txn.to;
-
-  const maxFee = ints[0];
-  // check fee
-  const tempTxn = new transaction.Transaction(txn);
-  if (tempTxn.fee > maxFee) {
-    throw new Error(
-      `final fee of payment transaction${tempTxn.fee.toString()}greater than transaction max fee${maxFee.toString()}`
-    );
-  }
-
-  return logicSig.signLogicSigTransaction(txn, lsig);
-}
-
-module.exports = {
-  HTLC,
-  signTransactionWithHTLCUnlock,
-};
diff --git a/src/logicTemplates/index.js b/src/logicTemplates/index.js
deleted file mode 100644
index 3996707..0000000
--- a/src/logicTemplates/index.js
+++ /dev/null
@@ -1,20 +0,0 @@
-const dynamicFeeTemplate = require('./dynamicfee');
-const htlcTemplate = require('./htlc');
-const limitOrderTemplate = require('./limitorder');
-const splitTemplate = require('./split');
-const periodicPayTemplate = require('./periodicpayment');
-
-module.exports = {
-  DynamicFee: dynamicFeeTemplate.DynamicFee,
-  getDynamicFeeTransactions: dynamicFeeTemplate.getDynamicFeeTransactions,
-  signDynamicFee: dynamicFeeTemplate.signDynamicFee,
-  HTLC: htlcTemplate.HTLC,
-  signTransactionWithHTLCUnlock: htlcTemplate.signTransactionWithHTLCUnlock,
-  LimitOrder: limitOrderTemplate.LimitOrder,
-  getSwapAssetsTransaction: limitOrderTemplate.getSwapAssetsTransaction,
-  Split: splitTemplate.Split,
-  getSplitFundsTransaction: splitTemplate.getSplitFundsTransaction,
-  PeriodicPayment: periodicPayTemplate.PeriodicPayment,
-  getPeriodicPaymentWithdrawalTransaction:
-    periodicPayTemplate.getPeriodicPaymentWithdrawalTransaction,
-};
diff --git a/src/logicTemplates/limitorder.js b/src/logicTemplates/limitorder.js
deleted file mode 100644
index c724e84..0000000
--- a/src/logicTemplates/limitorder.js
+++ /dev/null
@@ -1,227 +0,0 @@
-const address = require('../encoding/address');
-const makeTxn = require('../makeTxn');
-const group = require('../group');
-const logic = require('../logic/logic');
-const logicSig = require('../logicsig');
-const nacl = require('../nacl/naclWrappers');
-const templates = require('./templates');
-const utils = require('../utils/utils');
-
-class LimitOrder {
-  /**
-   * MakeLimitOrder allows a user to exchange some number of assets for some number of algos.
-   * Fund the contract with some number of Algos to limit the maximum number of
-   * Algos you're willing to trade for some other asset.
-   *
-   * Works on two cases:
-   * * trading Algos for some other asset
-   * * closing out Algos back to the originator after a timeout
-   *
-   * trade case, a 2 transaction group:
-   * gtxn[0] (this txn) Algos from Me to Other
-   * gtxn[1] asset from Other to Me
-   *
-   * We want to get _at least_ some amount of the other asset per our Algos
-   * gtxn[1].AssetAmount / gtxn[0].Amount >= N / D
-   * ===
-   * gtxn[1].AssetAmount * D >= gtxn[0].Amount * N
-   *
-   * close-out case:
-   * txn alone, close out value after timeout
-   *
-   * @deprecated This class will be removed in v2.
-   *
-   * Constructor Parameters:
-   * @param {string} owner: the address to refund funds to on timeout
-   * @param {int} assetid: the ID of the transferred asset
-   * @param {int} ratn: exchange rate (N asset per D Algos, or better)
-   * @param {int} ratd: exchange rate (N asset per D Algos, or better)
-   * @param {int} expiryRound: the round at which the account expires
-   * @param {int} minTrade: the minimum amount (of Algos) to be traded away
-   * @param {int} maxFee: maximum fee used by the limit order transaction
-   * @returns {LimitOrder}
-   */
-  constructor(owner, assetid, ratn, ratd, expiryRound, minTrade, maxFee) {
-    // don't need to validate owner - it will be validated by template.insert
-    if (!Number.isSafeInteger(assetid) || assetid < 0)
-      throw Error('assetid must be a positive number and smaller than 2^53-1');
-    if (!Number.isSafeInteger(ratn) || ratn < 0)
-      throw Error('ratn must be a positive number and smaller than 2^53-1');
-    if (!Number.isSafeInteger(ratd) || ratd < 0)
-      throw Error('ratd must be a positive number and smaller than 2^53-1');
-    if (!Number.isSafeInteger(expiryRound) || expiryRound < 0)
-      throw Error(
-        'expiryRound must be a positive number and smaller than 2^53-1'
-      );
-    if (!Number.isSafeInteger(minTrade) || minTrade < 0)
-      throw Error('minTrade must be a positive number and smaller than 2^53-1');
-    if (!Number.isSafeInteger(maxFee) || maxFee < 0)
-      throw Error('maxFee must be a positive number and smaller than 2^53-1');
-
-    const referenceProgramB64 =
-      'ASAKAAEFAgYEBwgJCiYBIP68oLsUSlpOp7Q4pGgayA5soQW8tgf8VlMlyVaV9qITMRYiEjEQIxIQMQEkDhAyBCMSQABVMgQlEjEIIQQNEDEJMgMSEDMBECEFEhAzAREhBhIQMwEUKBIQMwETMgMSEDMBEiEHHTUCNQExCCEIHTUENQM0ATQDDUAAJDQBNAMSNAI0BA8QQAAWADEJKBIxAiEJDRAxBzIDEhAxCCISEBA=';
-    const referenceProgramBytes = Buffer.from(referenceProgramB64, 'base64');
-    const referenceOffsets = [
-      5 /* minTrade */,
-      7 /* assetID */,
-      9 /* ratd */,
-      10 /* ratn */,
-      11 /* expiryRound */,
-      12 /* owner */,
-      16,
-    ];
-    const injectionVector = [
-      maxFee,
-      minTrade,
-      assetid,
-      ratd,
-      ratn,
-      expiryRound,
-      owner,
-    ];
-    const injectionTypes = [
-      templates.valTypes.INT,
-      templates.valTypes.INT,
-      templates.valTypes.INT,
-      templates.valTypes.INT,
-      templates.valTypes.INT,
-      templates.valTypes.INT,
-      templates.valTypes.ADDRESS,
-    ];
-    const injectedBytes = templates.inject(
-      referenceProgramBytes,
-      referenceOffsets,
-      injectionVector,
-      injectionTypes
-    );
-    this.programBytes = injectedBytes;
-    const lsig = new logicSig.LogicSig(injectedBytes, undefined);
-    this.address = lsig.address();
-    this.owner = owner;
-    this.assetid = assetid;
-  }
-
-  /**
-   * returns the program bytes
-   * @returns {Uint8Array}
-   */
-  getProgram() {
-    return this.programBytes;
-  }
-
-  /**
-   * returns the string address of the contract
-   * @returns {string}
-   */
-  getAddress() {
-    return this.address;
-  }
-}
-
-/**
- * returns a group transactions array which transfer funds according to the contract's ratio
- *
- * @deprecated This feature will be removed in v2.
- *
- * @param {Uint8Array} contract: byteform of the contract from the payer
- * @param {int} assetAmount: the amount of assets to be sent
- * @param {int} microAlgoAmount: number of microAlgos to transfer
- * @param {Uint8Array} secretKey: secret key for signing transaction
- * @param {int} fee: the fee per byte to pay in microAlgos
- * @param {int} firstRound: the first round on which these txns will be valid
- * @param {int} lastRound: the last round on which these txns will be valid
- * @param {string} genesisHash: the b64-encoded genesis hash indicating the network for this transaction
- * @returns {Uint8Array}
- * the first payment sends money (Algos) from contract to the recipient (we'll call him Buyer), closing the rest of the account to Owner
- * the second payment sends money (the asset) from Buyer to the Owner
- * these transactions will be rejected if they do not meet the restrictions set by the contract
- * @throws error if arguments fail contract validation
- */
-function getSwapAssetsTransaction(
-  contract,
-  assetAmount,
-  microAlgoAmount,
-  secretKey,
-  fee,
-  firstRound,
-  lastRound,
-  genesisHash
-) {
-  const buyerKeyPair = nacl.keyPairFromSecretKey(secretKey);
-  const buyerAddr = address.encodeAddress(buyerKeyPair.publicKey);
-  const programOutputs = logic.readProgram(contract, undefined);
-  const ints = programOutputs[0];
-  const byteArrays = programOutputs[1];
-
-  let noCloseRemainder;
-  let noAssetRevocationTarget;
-  const contractAssetID = ints[6];
-  const contractOwner = address.encodeAddress(byteArrays[0]);
-  const lsig = logicSig.makeLogicSig(contract, undefined);
-  const contractAddress = lsig.address();
-  const algosForAssets = makeTxn.makePaymentTxn(
-    contractAddress,
-    buyerAddr,
-    fee,
-    microAlgoAmount,
-    noCloseRemainder,
-    firstRound,
-    lastRound,
-    undefined,
-    genesisHash,
-    undefined
-  );
-  const assetsForAlgos = makeTxn.makeAssetTransferTxn(
-    buyerAddr,
-    contractOwner,
-    noCloseRemainder,
-    noAssetRevocationTarget,
-    fee,
-    assetAmount,
-    firstRound,
-    lastRound,
-    undefined,
-    genesisHash,
-    undefined,
-    contractAssetID
-  );
-  const txns = [algosForAssets, assetsForAlgos];
-  const txGroup = group.assignGroupID(txns);
-
-  const ratd = ints[7];
-  const ratn = ints[8];
-  if (assetAmount * ratd < microAlgoAmount * ratn) {
-    throw new Error(
-      `bad payment ratio, ${assetAmount.toString()}*${ratd.toString()} !>= ${microAlgoAmount.toString()}*${ratn.toString()}`
-    );
-  }
-  const minTrade = ints[4];
-  if (microAlgoAmount < minTrade) {
-    throw new Error(
-      `payment amount ${microAlgoAmount.toString()} less than minimum trade ${minTrade.toString()}`
-    );
-  }
-  const maxFee = ints[2];
-  if (txGroup[0].fee > maxFee) {
-    throw new Error(
-      `final fee of payment transaction ${txGroup[0].fee.toString()} greater than transaction max fee ${maxFee.toString()}`
-    );
-  }
-  if (txGroup[1].fee > maxFee) {
-    throw new Error(
-      `final fee of asset transaction ${txGroup[1].fee.toString()} greater than transaction max fee ${maxFee.toString()}`
-    );
-  }
-
-  const algosForAssetsSigned = logicSig.signLogicSigTransactionObject(
-    txGroup[0],
-    lsig
-  );
-  const assetsForAlgosSigned = txGroup[1].signTxn(secretKey);
-  return utils.concatArrays(algosForAssetsSigned.blob, assetsForAlgosSigned);
-}
-
-module.exports = {
-  LimitOrder,
-  getSwapAssetsTransaction,
-};
diff --git a/src/logicTemplates/periodicpayment.js b/src/logicTemplates/periodicpayment.js
deleted file mode 100644
index d001132..0000000
--- a/src/logicTemplates/periodicpayment.js
+++ /dev/null
@@ -1,208 +0,0 @@
-const address = require('../encoding/address');
-const makeTxn = require('../makeTxn');
-const logic = require('../logic/logic');
-const logicSig = require('../logicsig');
-const nacl = require('../nacl/naclWrappers');
-const templates = require('./templates');
-
-class PeriodicPayment {
-  /**
-   * MakePeriodicPayment allows some account to execute periodic withdrawal of funds.
-   * This is a contract account.
-   *
-   * This allows receiver to withdraw amount every
-   * period rounds for withdrawWindow after every multiple
-   * of period.
-   *
-   * After expiryRound, all remaining funds in the escrow
-   * are available to receiver.
-   *
-   * @deprecated This class will be removed in v2.
-   *
-   * Constructor Parameters:
-   * @param {string} receiver: address which is authorized to receive withdrawals
-   * @param {int} amount: the amount to send each period
-   * @param {int} withdrawalWindow: the duration of a withdrawal period
-   * @param {int} period: the time between a pair of withdrawal periods
-   * @param {int} expiryRound: the round at which the account expires
-   * @param {int} maxFee: maximum fee used by the withdrawal transaction
-   * @param {string} lease: b64 representation of lease to use, or leave undefined to generate one
-   * @returns {PeriodicPayment}
-   */
-  constructor(
-    receiver,
-    amount,
-    withdrawalWindow,
-    period,
-    expiryRound,
-    maxFee,
-    lease
-  ) {
-    // don't need to validate receiver or lease, it's validated by template insert
-    this.receiver = receiver;
-    if (!Number.isSafeInteger(amount) || amount < 0)
-      throw Error('amount must be a positive number and smaller than 2^53-1');
-    this.amount = amount;
-    if (!Number.isSafeInteger(withdrawalWindow) || withdrawalWindow < 0)
-      throw Error(
-        'withdrawalWindow must be a positive number and smaller than 2^53-1'
-      );
-    this.withdrawalWindow = withdrawalWindow;
-    if (!Number.isSafeInteger(period) || period < 0)
-      throw Error('period must be a positive number and smaller than 2^53-1');
-    this.period = period;
-    if (!Number.isSafeInteger(expiryRound) || expiryRound < 0)
-      throw Error(
-        'expiryRound must be a positive number and smaller than 2^53-1'
-      );
-    this.expiryRound = expiryRound;
-    if (!Number.isSafeInteger(maxFee) || maxFee < 0)
-      throw Error('maxFee must be a positive number and smaller than 2^53-1');
-    this.maxFee = maxFee;
-
-    if (lease === undefined) {
-      const leaseBytes = nacl.randomBytes(32);
-      this.lease = Buffer.from(leaseBytes).toString('base64');
-    } else {
-      this.lease = lease;
-    }
-
-    this.programBytes = this.getProgram();
-    const lsig = new logicSig.LogicSig(this.programBytes, undefined);
-    this.address = lsig.address();
-  }
-
-  /**
-   * returns the program bytes
-   * @returns {Uint8Array}
-   */
-  getProgram() {
-    const referenceProgramB64 =
-      'ASAHAQYFAAQDByYCIAECAwQFBgcIAQIDBAUGBwgBAgMEBQYHCAECAwQFBgcIIJKvkYTkEzwJf2arzJOxERsSogG9nQzKPkpIoc4TzPTFMRAiEjEBIw4QMQIkGCUSEDEEIQQxAggSEDEGKBIQMQkyAxIxBykSEDEIIQUSEDEJKRIxBzIDEhAxAiEGDRAxCCUSEBEQ';
-    const referenceProgramBytes = Buffer.from(referenceProgramB64, 'base64');
-    const referenceOffsets = [
-      4 /* period */,
-      5 /* withdrawWindow */,
-      7 /* amount */,
-      8 /* expiryRound */,
-      9 /* lease */,
-      12 /* receiver */,
-      46,
-    ];
-    const injectionVector = [
-      this.maxFee,
-      this.period,
-      this.withdrawalWindow,
-      this.amount,
-      this.expiryRound,
-      this.lease,
-      this.receiver,
-    ];
-    const injectionTypes = [
-      templates.valTypes.INT,
-      templates.valTypes.INT,
-      templates.valTypes.INT,
-      templates.valTypes.INT,
-      templates.valTypes.INT,
-      templates.valTypes.BASE64,
-      templates.valTypes.ADDRESS,
-    ];
-    return templates.inject(
-      referenceProgramBytes,
-      referenceOffsets,
-      injectionVector,
-      injectionTypes
-    );
-  }
-
-  /**
-   * returns the string address of the contract
-   * @returns {string}
-   */
-  getAddress() {
-    return this.address;
-  }
-}
-
-/**
- * getPeriodicPaymentWithdrawalTransaction returns a signed transaction extracting funds form the contract
- *
- * @deprecated This feature will be removed in v2.
- *
- * @param {Uint8Array} contract: the bytearray defining the contract, received from the payer
- * @param {int} fee: the fee per byte for the transaction
- * @param {int} firstValid: the first round on which the txn will be valid
- * @param {string} genesisHash: the hash representing the network for the txn
- * @returns {Object} Object containing txID and blob representing signed transaction
- * @throws error on failure
- */
-function getPeriodicPaymentWithdrawalTransaction(
-  contract,
-  fee,
-  firstValid,
-  genesisHash
-) {
-  const readResult = logic.readProgram(contract, undefined);
-  const ints = readResult[0];
-  const byteArrays = readResult[1];
-  const period = ints[2];
-  const duration = ints[4];
-  const amount = ints[5];
-  if (firstValid % period !== 0) {
-    throw new Error(
-      `firstValid round ${firstValid.toString()} was not a multiple of contract period ${period.toString()}`
-    );
-  }
-
-  // extract receiver and convert as needed
-  const receiverBytes = byteArrays[1];
-  const receiver = address.encodeAddress(receiverBytes);
-  // extract lease and convert
-  const leaseBuffer = byteArrays[0];
-  const lease = new Uint8Array(leaseBuffer);
-  const lastValid = firstValid + duration;
-  const to = receiver;
-  let noCloseRemainder;
-  let noNote;
-  const lsig = logicSig.makeLogicSig(contract, undefined);
-  const from = lsig.address();
-  const txn = {
-    from,
-    to,
-    fee,
-    amount,
-    closeRemainderTo: noCloseRemainder,
-    firstRound: firstValid,
-    lastRound: lastValid,
-    note: noNote,
-    genesisHash,
-    genesisID: '',
-    type: 'pay',
-    lease,
-  };
-
-  // check fee
-  const tempTxn = makeTxn.makePaymentTxn(
-    from,
-    to,
-    fee,
-    amount,
-    noCloseRemainder,
-    firstValid,
-    lastValid,
-    noNote,
-    genesisHash,
-    ''
-  );
-  if (tempTxn.fee > ints[1]) {
-    throw new Error(
-      `final fee of payment transaction${tempTxn.fee.toString()}greater than transaction max fee${ints[1].toString()}`
-    );
-  }
-
-  return logicSig.signLogicSigTransaction(txn, lsig);
-}
-module.exports = {
-  PeriodicPayment,
-  getPeriodicPaymentWithdrawalTransaction,
-};
diff --git a/src/logicTemplates/split.js b/src/logicTemplates/split.js
deleted file mode 100644
index 2f0ddcd..0000000
--- a/src/logicTemplates/split.js
+++ /dev/null
@@ -1,208 +0,0 @@
-const address = require('../encoding/address');
-const makeTxn = require('../makeTxn');
-const group = require('../group');
-const logicsig = require('../logicsig');
-const logic = require('../logic/logic');
-const templates = require('./templates');
-const utils = require('../utils/utils');
-
-class Split {
-  /**
-   * Split splits money sent to some account to two recipients at some ratio.
-   * This is a contract account.
-   *
-   * This allows either a two-transaction group, for executing a
-   * split, or single transaction, for closing the account.
-   *
-   * Withdrawals from this account are allowed as a group transaction which
-   * sends receiverOne and receiverTwo amounts with exactly the specified ratio:
-   * (rat1*amountForReceiverOne) = (rat2*amountForReceiverTwo)
-   * At least minPay must be sent to receiverOne.
-   * (CloseRemainderTo must be zero.)
-   *
-   * After expiryRound passes, all funds can be refunded to owner.
-   *
-   * @deprecated This feature will be removed in v2.
-   *
-   * Constructor Parameters:
-   * @param {string} owner: the address to refund funds to on timeout
-   * @param {string} receiverOne: the first recipient in the split account
-   * @param {string} receiverTwo: the second recipient in the split account
-   * @param {int} rat1: fraction of money to be paid to the 1st recipient
-   * @param {int} rat2: fraction of money to be paid to the 2nd recipient
-   * @param {int} expiryRound: the round at which the account expires
-   * @param {int} minPay: minimum amount to be paid out of the account
-   * @param {int} maxFee: half of the maximum fee used by each split forwarding group transaction
-   * @returns {Split}
-   */
-  constructor(
-    owner,
-    receiverOne,
-    receiverTwo,
-    rat1,
-    rat2,
-    expiryRound,
-    minPay,
-    maxFee
-  ) {
-    // don't need to validate owner, receiverone, receivertwo - they'll be validated by template.insert
-    if (!Number.isSafeInteger(rat2) || rat2 < 0)
-      throw Error('rat2 must be a positive number and smaller than 2^53-1');
-    if (!Number.isSafeInteger(rat1) || rat1 < 0)
-      throw Error('rat1 must be a positive number and smaller than 2^53-1');
-    if (!Number.isSafeInteger(expiryRound) || expiryRound < 0)
-      throw Error(
-        'expiryRound must be a positive number and smaller than 2^53-1'
-      );
-    if (!Number.isSafeInteger(minPay) || minPay < 0)
-      throw Error('minPay must be a positive number and smaller than 2^53-1');
-    if (!Number.isSafeInteger(maxFee) || maxFee < 0)
-      throw Error('maxFee must be a positive number and smaller than 2^53-1');
-
-    const referenceProgramB64 =
-      'ASAIAQUCAAYHCAkmAyCztwQn0+DycN+vsk+vJWcsoz/b7NDS6i33HOkvTpf+YiC3qUpIgHGWE8/1LPh9SGCalSN7IaITeeWSXbfsS5wsXyC4kBQ38Z8zcwWVAym4S8vpFB/c0XC6R4mnPi9EBADsPDEQIhIxASMMEDIEJBJAABkxCSgSMQcyAxIQMQglEhAxAiEEDRAiQAAuMwAAMwEAEjEJMgMSEDMABykSEDMBByoSEDMACCEFCzMBCCEGCxIQMwAIIQcPEBA=';
-    const referenceProgramBytes = Buffer.from(referenceProgramB64, 'base64');
-    const referenceOffsets = [
-      4 /* timeout */,
-      7 /* rat2 */,
-      8 /* rat1 */,
-      9 /* minPay */,
-      10 /* owner */,
-      14 /* receiver1 */,
-      47 /* receiver2 */,
-      80,
-    ];
-    const injectionVector = [
-      maxFee,
-      expiryRound,
-      rat2,
-      rat1,
-      minPay,
-      owner,
-      receiverOne,
-      receiverTwo,
-    ];
-    const injectionTypes = [
-      templates.valTypes.INT,
-      templates.valTypes.INT,
-      templates.valTypes.INT,
-      templates.valTypes.INT,
-      templates.valTypes.INT,
-      templates.valTypes.ADDRESS,
-      templates.valTypes.ADDRESS,
-      templates.valTypes.ADDRESS,
-    ];
-    const injectedBytes = templates.inject(
-      referenceProgramBytes,
-      referenceOffsets,
-      injectionVector,
-      injectionTypes
-    );
-    this.programBytes = injectedBytes;
-    const lsig = logicsig.makeLogicSig(injectedBytes, undefined);
-    this.address = lsig.address();
-  }
-
-  /**
-   * returns the program bytes
-   * @returns {Uint8Array}
-   */
-  getProgram() {
-    return this.programBytes;
-  }
-
-  /**
-   * returns the string address of the contract
-   * @returns {string}
-   */
-  getAddress() {
-    return this.address;
-  }
-}
-/**
- * returns a group transactions array which transfer funds according to the contract's ratio
- *
- * @deprecated This feature will be removed in v2.
- *
- * @param {Uint8Array} contract: bytes representing the contract in question
- * @param {int} amount: the amount to be transferred
- * @param {int} firstRound: the first round on which the transaction group will be valid
- * @param {int} lastRound: the last round on which the transaction group will be valid
- * @param {int} fee: the fee to pay in microAlgos
- * @param {string} genesisHash: the b64-encoded genesis hash indicating the network for this transaction
- * @returns {Uint8Array}
- */
-function getSplitFundsTransaction(
-  contract,
-  amount,
-  firstRound,
-  lastRound,
-  fee,
-  genesisHash
-) {
-  const programOutputs = logic.readProgram(contract, undefined);
-  const ints = programOutputs[0];
-  const byteArrays = programOutputs[1];
-  let rat2 = ints[6];
-  let rat1 = ints[5];
-  let amountForReceiverOne = 0;
-  // reduce fractions
-  const gcdFn = (a, b) => {
-    if (typeof a !== 'number' || typeof b !== 'number')
-      throw new Error('gcd operates only on positive integers');
-    if (!b) {
-      return a;
-    }
-    return gcdFn(b, a % b);
-  };
-  const gcd = gcdFn(rat2, rat1);
-  rat2 = Math.floor(rat2 / gcd);
-  rat1 = Math.floor(rat1 / gcd);
-  const ratio = rat1 / rat2;
-  amountForReceiverOne = Math.round(amount / (1 + ratio));
-  const amountForReceiverTwo = amount - amountForReceiverOne;
-  if (rat1 * amountForReceiverOne !== rat2 * amountForReceiverTwo) {
-    throw Error(
-      'could not split funds in a way that satisfied the contract ratio'
-    );
-  }
-
-  const logicSig = logicsig.makeLogicSig(contract, undefined); // no args
-  const from = logicSig.address();
-  const receiverOne = address.encodeAddress(byteArrays[1]);
-  const receiverTwo = address.encodeAddress(byteArrays[2]);
-  const tx1 = makeTxn.makePaymentTxn(
-    from,
-    receiverOne,
-    fee,
-    amountForReceiverOne,
-    undefined,
-    firstRound,
-    lastRound,
-    undefined,
-    genesisHash
-  );
-  const tx2 = makeTxn.makePaymentTxn(
-    from,
-    receiverTwo,
-    fee,
-    amountForReceiverTwo,
-    undefined,
-    firstRound,
-    lastRound,
-    undefined,
-    genesisHash
-  );
-  const txns = [tx1, tx2];
-  const txGroup = group.assignGroupID(txns);
-
-  const signedTxns = txGroup.map(
-    (txn) => logicsig.signLogicSigTransactionObject(txn, logicsig).blob
-  );
-  return utils.concatArrays(signedTxns[0], signedTxns[1]);
-}
-
-module.exports = {
-  Split,
-  getSplitFundsTransaction,
-};
diff --git a/src/logicTemplates/templates.js b/src/logicTemplates/templates.js
deleted file mode 100644
index cf8aa5f..0000000
--- a/src/logicTemplates/templates.js
+++ /dev/null
@@ -1,78 +0,0 @@
-/* eslint-disable no-bitwise */
-const address = require('../encoding/address');
-
-function putUvarint(buf, x) {
-  let i = 0;
-  while (x > 0x80) {
-    buf.push((x & 0xff) | 0x80);
-    // eslint-disable-next-line no-param-reassign
-    x >>= 7;
-    i += 1;
-  }
-  buf.push(x & 0xff);
-  return i + 1;
-}
-
-const valTypes = {
-  INT: 1,
-  ADDRESS: 2,
-  BASE64: 3,
-};
-
-function inject(orig, offsets, values, valueTypes) {
-  if (
-    offsets.length !== values.length ||
-    offsets.length !== valueTypes.length
-  ) {
-    throw new Error('Lengths do not match');
-  }
-
-  let res = orig;
-
-  function replace(arr, newVal, offset, placeholderLength) {
-    const beforeReplacement = arr.slice(0, offset);
-    const afterReplacement = arr.slice(offset + placeholderLength, arr.length);
-    const chunks = [beforeReplacement, Buffer.from(newVal), afterReplacement];
-    return Buffer.concat(chunks);
-  }
-
-  for (let i = 0; i < offsets.length; i++) {
-    let decodedLength = 0;
-    let val = values[i];
-    const valType = valueTypes[i];
-
-    switch (valType) {
-      case valTypes.INT:
-        // eslint-disable-next-line no-case-declarations
-        const intBuf = [];
-        decodedLength = putUvarint(intBuf, val);
-        res = replace(res, intBuf, offsets[i], 1);
-        break;
-      case valTypes.ADDRESS:
-        val = address.decodeAddress(val);
-        res = replace(res, val.publicKey, offsets[i], 32);
-        break;
-      case valTypes.BASE64:
-        // eslint-disable-next-line no-case-declarations
-        const lenBuf = [];
-        val = Buffer.from(val, 'base64');
-        putUvarint(lenBuf, val.length);
-        val = Buffer.concat([Buffer.from(lenBuf), val]);
-        res = replace(res, val, offsets[i], 33);
-        break;
-      default:
-        throw new Error('unrecognized value type');
-    }
-
-    if (decodedLength !== 0) {
-      for (let o = 0; o < offsets.length; o++) {
-        // eslint-disable-next-line no-param-reassign
-        offsets[o] += decodedLength - 1;
-      }
-    }
-  }
-
-  return res;
-}
-
-module.exports = { inject, valTypes };
diff --git a/src/logicsig.ts b/src/logicsig.ts
index 74c0e0b..c63e6af 100644
--- a/src/logicsig.ts
+++ b/src/logicsig.ts
@@ -54,6 +54,8 @@ export function sanityCheckProgram(program: Uint8Array) {
 
 /**
  LogicSig implementation
+
+ LogicSig cannot sign transactions in all cases.  Instead, use LogicSigAccount as a safe, general purpose signing mechanism.  Since LogicSig does not track the provided signature's public key, LogicSig cannot sign transactions when delegated to a non-multisig account _and_ the sender is not the delegating account.
  */
 export class LogicSig implements LogicSigStorageStructure {
   tag = Buffer.from('Program');
@@ -375,19 +377,6 @@ export class LogicSigAccount {
   }
 }
 
-/**
- * makeLogicSig creates LogicSig object from program and arguments
- *
- * @deprecated Use new LogicSigAccount(...) instead
- *
- * @param program - Program to make LogicSig from
- * @param args - Arguments as array of Uint8Array
- * @returns LogicSig object
- */
-export function makeLogicSig(program: Uint8Array, args?: Uint8Array[]) {
-  return new LogicSig(program, args);
-}
-
 function signLogicSigTransactionWithAddress(
   txn: txnBuilder.Transaction,
   lsig: LogicSig,
diff --git a/src/main.ts b/src/main.ts
index 4d80ec3..2fa4d21 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -2,7 +2,6 @@ import * as nacl from './nacl/naclWrappers';
 import * as address from './encoding/address';
 import * as encoding from './encoding/encoding';
 import * as txnBuilder from './transaction';
-import * as LogicTemplatesCommonJSExport from './logicTemplates';
 import Bid, { BidOptions } from './bid';
 import * as convert from './convert';
 import * as utils from './utils/utils';
@@ -117,7 +116,6 @@ export const ERROR_INVALID_MICROALGOS = new Error(
   convert.INVALID_MICROALGOS_ERROR_MSG
 );
 
-export * from './client/algod';
 export { default as Algodv2 } from './client/v2/algod/algod';
 export { default as Kmd } from './client/kmd';
 export { default as IntDecoding } from './types/intDecoding';
@@ -155,8 +153,8 @@ export {
 } from './convert';
 export { computeGroupID, assignGroupID } from './group';
 export {
+  LogicSig,
   LogicSigAccount,
-  makeLogicSig,
   signLogicSigTransaction,
   signLogicSigTransactionObject,
   logicSigFromByte,
@@ -174,8 +172,6 @@ export {
 } from './multisig';
 export { SourceMap } from './logic/sourcemap';
 
-export const LogicTemplates = LogicTemplatesCommonJSExport.default;
-
 export * from './dryrun';
 export * from './makeTxn';
 export * from './transaction';
diff --git a/src/makeTxn.ts b/src/makeTxn.ts
index 18152f7..b62f364 100644
--- a/src/makeTxn.ts
+++ b/src/makeTxn.ts
@@ -7,9 +7,7 @@ import {
 
   // Utilities
   TransactionType,
-  SuggestedParams,
   MustHaveSuggestedParams,
-  MustHaveSuggestedParamsInline,
   AssetCreateTxn,
   AssetConfigTxn,
   AssetDestroyTxn,
@@ -64,53 +62,6 @@ export function makePaymentTxnWithSuggestedParams(
   return new txnBuilder.Transaction(o);
 }
 
-/**
- * makePaymentTxn takes payment arguments and returns a Transaction object
- * @param from - string representation of Algorand address of sender
- * @param to - string representation of Algorand address of recipient
- * @param fee - integer fee per byte, in microAlgos. for a flat fee, overwrite the fee property on the returned object
- * If the final calculated fee is lower than the protocol minimum fee, the fee will be increased to match the minimum.
- * @param amount - integer amount to send, in microAlgos
- * @param closeRemainderTo - optionally close out remaining account balance to this account, represented as string rep of Algorand address
- * @param firstRound - integer first protocol round on which this txn is valid
- * @param lastRound - integer last protocol round on which this txn is valid
- * @param note - uint8array of arbitrary data for sender to store
- * @param genesisHash - string specifies hash genesis block of network in use
- * @param genesisID - string specifies genesis ID of network in use
- * @param rekeyTo - rekeyTo address, optional
- * @Deprecated in version 2.0 this will change to use the "WithSuggestedParams" signature.
- */
-export function makePaymentTxn(
-  from: PaymentTxn['from'],
-  to: PaymentTxn['to'],
-  fee: MustHaveSuggestedParamsInline<PaymentTxn>['fee'],
-  amount: PaymentTxn['amount'],
-  closeRemainderTo: PaymentTxn['closeRemainderTo'],
-  firstRound: MustHaveSuggestedParamsInline<PaymentTxn>['firstRound'],
-  lastRound: MustHaveSuggestedParamsInline<PaymentTxn>['lastRound'],
-  note: PaymentTxn['note'],
-  genesisHash: MustHaveSuggestedParamsInline<PaymentTxn>['genesisHash'],
-  genesisID: MustHaveSuggestedParamsInline<PaymentTxn>['genesisID'],
-  rekeyTo?: PaymentTxn['reKeyTo']
-) {
-  const suggestedParams: SuggestedParams = {
-    genesisHash,
-    genesisID,
-    firstRound,
-    lastRound,
-    fee,
-  };
-  return makePaymentTxnWithSuggestedParams(
-    from,
-    to,
-    amount,
-    closeRemainderTo,
-    note,
-    suggestedParams,
-    rekeyTo
-  );
-}
-
 // helper for above makePaymentTxnWithSuggestedParams, instead accepting an arguments object
 export function makePaymentTxnWithSuggestedParamsFromObject(
   o: Expand<
@@ -217,102 +168,6 @@ export function makeKeyRegistrationTxnWithSuggestedParams(
   return new txnBuilder.Transaction(o);
 }
 
-/**
- * makeKeyRegistrationTxn takes key registration arguments and returns a Transaction object for
- * that key registration operation
- *
- * @param from - string representation of Algorand address of sender
- * @param fee - integer fee per byte, in microAlgos. for a flat fee, overwrite the fee property on the returned object
- *  If the final calculated fee is lower than the protocol minimum fee, the fee will be increased to match the minimum.
- * @param firstRound - integer first protocol round on which this txn is valid
- * @param lastRound - integer last protocol round on which this txn is valid
- * @param note - uint8array of arbitrary data for sender to store
- * @param genesisHash - string specifies hash genesis block of network in use
- * @param genesisID - string specifies genesis ID of network in use
- * @param voteKey - voting key. for key deregistration, leave undefined
- * @param selectionKey - selection key. for key deregistration, leave undefined
- * @param voteFirst - first round on which voteKey is valid
- * @param voteLast - last round on which voteKey is valid
- * @param voteKeyDilution - integer
- * @param rekeyTo - rekeyTo address, optional
- * @param nonParticipation - configure whether the address wants to stop participating. If true,
- *   voteKey, selectionKey, voteFirst, voteLast, and voteKeyDilution must be undefined.
- * @param stateProofKey - state proof key. for key deregistration, leave undefined
- * @Deprecated in version 2.0 this will change to use the "WithSuggestedParams" signature.
- */
-export function makeKeyRegistrationTxn(
-  from: KeyRegistrationTxn['from'],
-  fee: MustHaveSuggestedParamsInline<KeyRegistrationTxn>['fee'],
-  firstRound: MustHaveSuggestedParamsInline<KeyRegistrationTxn>['firstRound'],
-  lastRound: MustHaveSuggestedParamsInline<KeyRegistrationTxn>['lastRound'],
-  note: KeyRegistrationTxn['note'],
-  genesisHash: MustHaveSuggestedParamsInline<KeyRegistrationTxn>['genesisHash'],
-  genesisID: MustHaveSuggestedParamsInline<KeyRegistrationTxn>['genesisID'],
-  voteKey: KeyRegistrationTxn['voteKey'],
-  selectionKey: KeyRegistrationTxn['selectionKey'],
-  voteFirst: KeyRegistrationTxn['voteFirst'],
-  voteLast: KeyRegistrationTxn['voteLast'],
-  voteKeyDilution: KeyRegistrationTxn['voteKeyDilution'],
-  rekeyTo?: KeyRegistrationTxn['reKeyTo'],
-  nonParticipation?: false,
-  stateProofKey?: KeyRegistrationTxn['stateProofKey']
-): txnBuilder.Transaction;
-export function makeKeyRegistrationTxn(
-  from: KeyRegistrationTxn['from'],
-  fee: MustHaveSuggestedParamsInline<KeyRegistrationTxn>['fee'],
-  firstRound: MustHaveSuggestedParamsInline<KeyRegistrationTxn>['firstRound'],
-  lastRound: MustHaveSuggestedParamsInline<KeyRegistrationTxn>['lastRound'],
-  note: KeyRegistrationTxn['note'],
-  genesisHash: MustHaveSuggestedParamsInline<KeyRegistrationTxn>['genesisHash'],
-  genesisID: MustHaveSuggestedParamsInline<KeyRegistrationTxn>['genesisID'],
-  voteKey: undefined,
-  selectionKey: undefined,
-  voteFirst: undefined,
-  voteLast: undefined,
-  voteKeyDilution: undefined,
-  rekeyTo?: KeyRegistrationTxn['reKeyTo'],
-  nonParticipation?: true,
-  stateProofKey?: undefined
-): txnBuilder.Transaction;
-export function makeKeyRegistrationTxn(
-  from: any,
-  fee: any,
-  firstRound: any,
-  lastRound: any,
-  note: any,
-  genesisHash: any,
-  genesisID: any,
-  voteKey: any,
-  selectionKey: any,
-  voteFirst: any,
-  voteLast: any,
-  voteKeyDilution: any,
-  rekeyTo?: any,
-  nonParticipation: any = false,
-  stateProofKey: any = undefined
-) {
-  const suggestedParams: SuggestedParams = {
-    genesisHash,
-    genesisID,
-    firstRound,
-    lastRound,
-    fee,
-  };
-  return makeKeyRegistrationTxnWithSuggestedParams(
-    from,
-    note,
-    voteKey,
-    selectionKey,
-    voteFirst,
-    voteLast,
-    voteKeyDilution,
-    suggestedParams,
-    rekeyTo,
-    nonParticipation,
-    stateProofKey
-  );
-}
-
 // helper for above makeKeyRegistrationTxnWithSuggestedParams, instead accepting an arguments object
 export function makeKeyRegistrationTxnWithSuggestedParamsFromObject(
   o: Expand<
@@ -431,78 +286,6 @@ export function makeAssetCreateTxnWithSuggestedParams(
   return new txnBuilder.Transaction(o);
 }
 
-/** makeAssetCreateTxn takes asset creation arguments and returns a Transaction object
- * for creating that asset
- *
- * @param from - string representation of Algorand address of sender
- * @param fee - integer fee per byte, in microAlgos. for a flat fee, overwrite the fee property on the returned object
- *  If the final calculated fee is lower than the protocol minimum fee, the fee will be increased to match the minimum.
- * @param firstRound - integer first protocol round on which this txn is valid
- * @param lastRound - integer last protocol round on which this txn is valid
- * @param note - uint8array of arbitrary data for sender to store
- * @param genesisHash - string specifies hash genesis block of network in use
- * @param genesisID - string specifies genesis ID of network in use
- * @param total - integer total supply of the asset
- * @param decimals - integer number of decimals for asset unit calculation
- * @param defaultFrozen - boolean whether asset accounts should default to being frozen
- * @param manager - string representation of Algorand address in charge of reserve, freeze, clawback, destruction, etc
- * @param reserve - string representation of Algorand address representing asset reserve
- * @param freeze - string representation of Algorand address with power to freeze/unfreeze asset holdings
- * @param clawback - string representation of Algorand address with power to revoke asset holdings
- * @param unitName - string units name for this asset
- * @param assetName - string name for this asset
- * @param assetURL - string URL relating to this asset
- * @param assetMetadataHash - Uint8Array or UTF-8 string representation of a hash commitment with respect to the asset. Must be exactly 32 bytes long.
- * @param rekeyTo - rekeyTo address, optional
- * @Deprecated in version 2.0 this will change to use the "WithSuggestedParams" signature.
- */
-export function makeAssetCreateTxn(
-  from: AssetCreateTxn['from'],
-  fee: MustHaveSuggestedParamsInline<AssetCreateTxn>['fee'],
-  firstRound: MustHaveSuggestedParamsInline<AssetCreateTxn>['firstRound'],
-  lastRound: MustHaveSuggestedParamsInline<AssetCreateTxn>['lastRound'],
-  note: AssetCreateTxn['note'],
-  genesisHash: MustHaveSuggestedParamsInline<AssetCreateTxn>['genesisHash'],
-  genesisID: MustHaveSuggestedParamsInline<AssetCreateTxn>['genesisID'],
-  total: AssetCreateTxn['assetTotal'],
-  decimals: AssetCreateTxn['assetDecimals'],
-  defaultFrozen: AssetCreateTxn['assetDefaultFrozen'],
-  manager: AssetCreateTxn['assetManager'],
-  reserve: AssetCreateTxn['assetManager'],
-  freeze: AssetCreateTxn['assetFreeze'],
-  clawback: AssetCreateTxn['assetClawback'],
-  unitName: AssetCreateTxn['assetUnitName'],
-  assetName: AssetCreateTxn['assetName'],
-  assetURL: AssetCreateTxn['assetURL'],
-  assetMetadataHash?: AssetCreateTxn['assetMetadataHash'],
-  rekeyTo?: AssetCreateTxn['reKeyTo']
-) {
-  const suggestedParams: SuggestedParams = {
-    genesisHash,
-    genesisID,
-    firstRound,
-    lastRound,
-    fee,
-  };
-  return makeAssetCreateTxnWithSuggestedParams(
-    from,
-    note,
-    total,
-    decimals,
-    defaultFrozen,
-    manager,
-    reserve,
-    freeze,
-    clawback,
-    unitName,
-    assetName,
-    assetURL,
-    assetMetadataHash,
-    suggestedParams,
-    rekeyTo
-  );
-}
-
 // helper for above makeAssetCreateTxnWithSuggestedParams, instead accepting an arguments object
 export function makeAssetCreateTxnWithSuggestedParamsFromObject(
   o: Expand<
@@ -618,64 +401,6 @@ export function makeAssetConfigTxnWithSuggestedParams(
   return new txnBuilder.Transaction(o);
 }
 
-/** makeAssetConfigTxn can be issued by the asset manager to change the manager, reserve, freeze, or clawback
- * you must respecify existing addresses to keep them the same; leaving a field blank is the same as turning
- * that feature off for this asset
- *
- * @param from - string representation of Algorand address of sender
- * @param fee - integer fee per byte, in microAlgos. for a flat fee, overwrite the fee property on the returned object
- *  If the final calculated fee is lower than the protocol minimum fee, the fee will be increased to match the minimum.
- * @param firstRound - integer first protocol round on which this txn is valid
- * @param lastRound - integer last protocol round on which this txn is valid
- * @param note - uint8array of arbitrary data for sender to store
- * @param genesisHash - string specifies hash genesis block of network in use
- * @param genesisID - string specifies genesis ID of network in use
- * @param assetIndex - int asset index uniquely specifying the asset
- * @param manager - string representation of new asset manager Algorand address
- * @param reserve - string representation of new reserve Algorand address
- * @param freeze - string representation of new freeze manager Algorand address
- * @param clawback - string representation of new revocation manager Algorand address
- * @param strictEmptyAddressChecking - boolean - throw an error if any of manager, reserve, freeze, or clawback are undefined. optional, defaults to true.
- * @param rekeyTo - rekeyTo address, optional
- * @Deprecated in version 2.0 this will change to use the "WithSuggestedParams" signature.
- */
-export function makeAssetConfigTxn(
-  from: AssetConfigTxn['from'],
-  fee: MustHaveSuggestedParamsInline<AssetConfigTxn>['fee'],
-  firstRound: MustHaveSuggestedParamsInline<AssetConfigTxn>['firstRound'],
-  lastRound: MustHaveSuggestedParamsInline<AssetConfigTxn>['lastRound'],
-  note: AssetConfigTxn['note'],
-  genesisHash: MustHaveSuggestedParamsInline<AssetConfigTxn>['genesisHash'],
-  genesisID: MustHaveSuggestedParamsInline<AssetConfigTxn>['genesisID'],
-  assetIndex: AssetConfigTxn['assetIndex'],
-  manager: AssetConfigTxn['assetManager'],
-  reserve: AssetConfigTxn['assetReserve'],
-  freeze: AssetConfigTxn['assetFreeze'],
-  clawback: AssetConfigTxn['assetClawback'],
-  strictEmptyAddressChecking = true,
-  rekeyTo?: AssetConfigTxn['reKeyTo']
-) {
-  const suggestedParams: SuggestedParams = {
-    genesisHash,
-    genesisID,
-    firstRound,
-    lastRound,
-    fee,
-  };
-  return makeAssetConfigTxnWithSuggestedParams(
-    from,
-    note,
-    assetIndex,
-    manager,
-    reserve,
-    freeze,
-    clawback,
-    suggestedParams,
-    strictEmptyAddressChecking,
-    rekeyTo
-  );
-}
-
 // helper for above makeAssetConfigTxnWithSuggestedParams, instead accepting an arguments object
 export function makeAssetConfigTxnWithSuggestedParamsFromObject(
   o: Expand<
@@ -752,48 +477,6 @@ export function makeAssetDestroyTxnWithSuggestedParams(
   return new txnBuilder.Transaction(o);
 }
 
-/** makeAssetDestroyTxn will allow the asset's manager to remove this asset from the ledger, so long
- * as all outstanding assets are held by the creator.
- *
- * @param from - string representation of Algorand address of sender
- * @param fee - integer fee per byte, in microAlgos. for a flat fee, overwrite the fee property on the returned object
- *  If the final calculated fee is lower than the protocol minimum fee, the fee will be increased to match the minimum.
- * @param firstRound - integer first protocol round on which this txn is valid
- * @param lastRound - integer last protocol round on which this txn is valid
- * @param note - uint8array of arbitrary data for sender to store
- * @param genesisHash - string specifies hash genesis block of network in use
- * @param genesisID - string specifies genesis ID of network in use
- * @param assetIndex - int asset index uniquely specifying the asset
- * @param rekeyTo - rekeyTo address, optional
- * @Deprecated in version 2.0 this will change to use the "WithSuggestedParams" signature.
- */
-export function makeAssetDestroyTxn(
-  from: AssetDestroyTxn['from'],
-  fee: MustHaveSuggestedParamsInline<AssetDestroyTxn>['fee'],
-  firstRound: MustHaveSuggestedParamsInline<AssetDestroyTxn>['firstRound'],
-  lastRound: MustHaveSuggestedParamsInline<AssetDestroyTxn>['lastRound'],
-  note: AssetDestroyTxn['note'],
-  genesisHash: MustHaveSuggestedParamsInline<AssetDestroyTxn>['genesisHash'],
-  genesisID: MustHaveSuggestedParamsInline<AssetDestroyTxn>['genesisID'],
-  assetIndex: AssetDestroyTxn['assetIndex'],
-  rekeyTo?: AssetDestroyTxn['reKeyTo']
-) {
-  const suggestedParams: SuggestedParams = {
-    genesisHash,
-    genesisID,
-    firstRound,
-    lastRound,
-    fee,
-  };
-  return makeAssetDestroyTxnWithSuggestedParams(
-    from,
-    note,
-    assetIndex,
-    suggestedParams,
-    rekeyTo
-  );
-}
-
 // helper for above makeAssetDestroyTxnWithSuggestedParams, instead accepting an arguments object
 export function makeAssetDestroyTxnWithSuggestedParamsFromObject(
   o: Expand<
@@ -856,54 +539,6 @@ export function makeAssetFreezeTxnWithSuggestedParams(
   return new txnBuilder.Transaction(o);
 }
 
-/** makeAssetFreezeTxn will allow the asset's freeze manager to freeze or un-freeze an account,
- * blocking or allowing asset transfers to and from the targeted account.
- *
- * @param from - string representation of Algorand address of sender
- * @param fee - integer fee per byte, in microAlgos. for a flat fee, overwrite the fee property on the returned object
- *  If the final calculated fee is lower than the protocol minimum fee, the fee will be increased to match the minimum.
- * @param firstRound - integer first protocol round on which this txn is valid
- * @param lastRound - integer last protocol round on which this txn is valid
- * @param note - uint8array of arbitrary data for sender to store
- * @param genesisHash - string specifies hash genesis block of network in use
- * @param genesisID - string specifies genesis ID of network in use
- * @param assetIndex - int asset index uniquely specifying the asset
- * @param freezeTarget - string representation of Algorand address being frozen or unfrozen
- * @param freezeState - true if freezeTarget should be frozen, false if freezeTarget should be allowed to transact
- * @param rekeyTo - rekeyTo address, optional
- * @Deprecated in version 2.0 this will change to use the "WithSuggestedParams" signature.
- */
-export function makeAssetFreezeTxn(
-  from: AssetFreezeTxn['from'],
-  fee: MustHaveSuggestedParamsInline<AssetFreezeTxn>['fee'],
-  firstRound: MustHaveSuggestedParamsInline<AssetFreezeTxn>['firstRound'],
-  lastRound: MustHaveSuggestedParamsInline<AssetFreezeTxn>['lastRound'],
-  note: MustHaveSuggestedParamsInline<AssetFreezeTxn>['note'],
-  genesisHash: MustHaveSuggestedParamsInline<AssetFreezeTxn>['genesisHash'],
-  genesisID: MustHaveSuggestedParamsInline<AssetFreezeTxn>['genesisID'],
-  assetIndex: AssetFreezeTxn['assetIndex'],
-  freezeTarget: AssetFreezeTxn['freezeAccount'],
-  freezeState: AssetFreezeTxn['freezeState'],
-  rekeyTo?: AssetFreezeTxn['reKeyTo']
-) {
-  const suggestedParams: SuggestedParams = {
-    genesisHash,
-    genesisID,
-    firstRound,
-    lastRound,
-    fee,
-  };
-  return makeAssetFreezeTxnWithSuggestedParams(
-    from,
-    note,
-    assetIndex,
-    freezeTarget,
-    freezeState,
-    suggestedParams,
-    rekeyTo
-  );
-}
-
 // helper for above makeAssetFreezeTxnWithSuggestedParams, instead accepting an arguments object
 export function makeAssetFreezeTxnWithSuggestedParamsFromObject(
   o: Expand<
@@ -986,62 +621,6 @@ export function makeAssetTransferTxnWithSuggestedParams(
   return new txnBuilder.Transaction(o);
 }
 
-/** makeAssetTransferTxn allows for the creation of an asset transfer transaction.
- * Special case: to begin accepting assets, set amount=0 and from=to.
- *
- * @param from - string representation of Algorand address of sender
- * @param to - string representation of Algorand address of asset recipient
- * @param closeRemainderTo - optional - string representation of Algorand address - if provided,
- * send all remaining assets after transfer to the "closeRemainderTo" address and close "from"'s asset holdings
- * @param revocationTarget - optional - string representation of Algorand address - if provided,
- * and if "from" is the asset's revocation manager, then deduct from "revocationTarget" rather than "from"
- * @param fee - integer fee per byte, in microAlgos. for a flat fee, overwrite the fee property on the returned object
- *  If the final calculated fee is lower than the protocol minimum fee, the fee will be increased to match the minimum.
- * @param amount - integer amount of assets to send
- * @param firstRound - integer first protocol round on which this txn is valid
- * @param lastRound - integer last protocol round on which this txn is valid
- * @param note - uint8array of arbitrary data for sender to store
- * @param genesisHash - string specifies hash genesis block of network in use
- * @param genesisID - string specifies genesis ID of network in use
- * @param assetIndex - int asset index uniquely specifying the asset
- * @param rekeyTo - rekeyTo address, optional
- * @Deprecated in version 2.0 this will change to use the "WithSuggestedParams" signature.
- */
-export function makeAssetTransferTxn(
-  from: AssetTransferTxn['from'],
-  to: AssetTransferTxn['to'],
-  closeRemainderTo: AssetTransferTxn['closeRemainderTo'],
-  revocationTarget: AssetTransferTxn['assetRevocationTarget'],
-  fee: MustHaveSuggestedParamsInline<AssetTransferTxn>['fee'],
-  amount: AssetTransferTxn['amount'],
-  firstRound: MustHaveSuggestedParamsInline<AssetTransferTxn>['firstRound'],
-  lastRound: MustHaveSuggestedParamsInline<AssetTransferTxn>['lastRound'],
-  note: AssetTransferTxn['note'],
-  genesisHash: MustHaveSuggestedParamsInline<AssetTransferTxn>['genesisHash'],
-  genesisID: MustHaveSuggestedParamsInline<AssetTransferTxn>['genesisID'],
-  assetIndex: AssetTransferTxn['assetIndex'],
-  rekeyTo?: AssetTransferTxn['reKeyTo']
-) {
-  const suggestedParams: SuggestedParams = {
-    genesisHash,
-    genesisID,
-    firstRound,
-    lastRound,
-    fee,
-  };
-  return makeAssetTransferTxnWithSuggestedParams(
-    from,
-    to,
-    closeRemainderTo,
-    revocationTarget,
-    amount,
-    note,
-    assetIndex,
-    suggestedParams,
-    rekeyTo
-  );
-}
-
 // helper for above makeAssetTransferTxnWithSuggestedParams, instead accepting an arguments object
 export function makeAssetTransferTxnWithSuggestedParamsFromObject(
   o: Expand<
diff --git a/src/types/transactions/encoded.ts b/src/types/transactions/encoded.ts
index ff3d560..2f0f48e 100644
--- a/src/types/transactions/encoded.ts
+++ b/src/types/transactions/encoded.ts
@@ -363,23 +363,6 @@ export interface EncodedMultisig {
   subsig: EncodedSubsig[];
 }
 
-/**
- * An encoded multisig blob that contains the encoded multisig as well as a copy of the encoded transaction
- *
- * @deprecated Use EncodedSignedTransaction instead.
- */
-export interface EncodedMultisigBlob {
-  /**
-   * Encoded multisig
-   */
-  msig: EncodedMultisig;
-
-  /**
-   * Encoded transaction
-   */
-  txn: EncodedTransaction;
-}
-
 export interface EncodedLogicSig {
   l: Uint8Array;
   arg?: Uint8Array[];


Test patch:
diff --git a/tests/5.Transaction.js b/tests/5.Transaction.js
index 5c8466a..0b2d3b3 100644
--- a/tests/5.Transaction.js
+++ b/tests/5.Transaction.js
@@ -737,17 +737,20 @@ describe('Sign', () => {
         reKeyTo: rekeyTo,
       };
       const expectedTxn = new algosdk.Transaction(o);
-      const actualTxn = algosdk.makePaymentTxn(
+      const suggestedParams = {
+        genesisHash,
+        genesisID,
+        firstRound,
+        lastRound,
+        fee,
+      };
+      const actualTxn = algosdk.makePaymentTxnWithSuggestedParams(
         from,
         to,
-        fee,
         amount,
         closeRemainderTo,
-        firstRound,
-        lastRound,
         note,
-        genesisHash,
-        genesisID,
+        suggestedParams,
         rekeyTo
       );
       assert.deepStrictEqual(expectedTxn, actualTxn);
@@ -780,17 +783,20 @@ describe('Sign', () => {
         reKeyTo: rekeyTo,
       };
       const expectedTxn = new algosdk.Transaction(o);
-      const actualTxn = algosdk.makePaymentTxn(
+      const suggestedParams = {
+        genesisHash,
+        genesisID,
+        firstRound,
+        lastRound,
+        fee,
+      };
+      const actualTxn = algosdk.makePaymentTxnWithSuggestedParams(
         from,
         to,
-        fee,
         amount,
         closeRemainderTo,
-        firstRound,
-        lastRound,
         note,
-        genesisHash,
-        genesisID,
+        suggestedParams,
         rekeyTo
       );
       assert.deepStrictEqual(expectedTxn, actualTxn);
@@ -862,19 +868,22 @@ describe('Sign', () => {
         type: 'keyreg',
       };
       const expectedTxn = new algosdk.Transaction(o);
-      const actualTxn = algosdk.makeKeyRegistrationTxn(
-        from,
-        fee,
+      const suggestedParams = {
+        genesisHash,
+        genesisID,
         firstRound,
         lastRound,
+        fee,
+      };
+      const actualTxn = algosdk.makeKeyRegistrationTxnWithSuggestedParams(
+        from,
         note,
-        genesisHash,
-        genesisID,
         voteKey,
         selectionKey,
         voteFirst,
         voteLast,
         voteKeyDilution,
+        suggestedParams,
         rekeyTo
       );
       assert.deepStrictEqual(expectedTxn, actualTxn);
@@ -926,19 +935,22 @@ describe('Sign', () => {
       );
 
       const expectedTxn = new algosdk.Transaction(o);
-      const actualTxn = algosdk.makeKeyRegistrationTxn(
-        from,
-        fee,
+      const suggestedParams = {
+        genesisHash,
+        genesisID,
         firstRound,
         lastRound,
+        fee,
+      };
+      const actualTxn = algosdk.makeKeyRegistrationTxnWithSuggestedParams(
+        from,
         note,
-        genesisHash,
-        genesisID,
         voteKey,
         selectionKey,
         voteFirst,
         voteLast,
         voteKeyDilution,
+        suggestedParams,
         rekeyTo
       );
       assert.deepStrictEqual(expectedTxn, actualTxn);
@@ -989,19 +1001,22 @@ describe('Sign', () => {
       );
 
       const expectedTxn = new algosdk.Transaction(o);
-      const actualTxn = algosdk.makeKeyRegistrationTxn(
-        from,
-        fee,
+      const suggestedParams = {
+        genesisHash,
+        genesisID,
         firstRound,
         lastRound,
+        fee,
+      };
+      const actualTxn = algosdk.makeKeyRegistrationTxnWithSuggestedParams(
+        from,
         note,
-        genesisHash,
-        genesisID,
         undefined,
         undefined,
         undefined,
         undefined,
         undefined,
+        suggestedParams,
         rekeyTo,
         nonParticipation
       );
@@ -1053,14 +1068,16 @@ describe('Sign', () => {
         type: 'acfg',
       };
       const expectedTxn = new algosdk.Transaction(o);
-      const actualTxn = algosdk.makeAssetCreateTxn(
-        addr,
-        fee,
+      const suggestedParams = {
+        genesisHash,
+        genesisID,
         firstRound,
         lastRound,
+        fee,
+      };
+      const actualTxn = algosdk.makeAssetCreateTxnWithSuggestedParams(
+        addr,
         note,
-        genesisHash,
-        genesisID,
         total,
         decimals,
         defaultFrozen,
@@ -1072,6 +1089,7 @@ describe('Sign', () => {
         assetName,
         assetURL,
         assetMetadataHash,
+        suggestedParams,
         rekeyTo
       );
       assert.deepStrictEqual(expectedTxn, actualTxn);
@@ -1122,14 +1140,16 @@ describe('Sign', () => {
         type: 'acfg',
       };
       const expectedTxn = new algosdk.Transaction(o);
-      const actualTxn = algosdk.makeAssetCreateTxn(
-        addr,
-        fee,
+      const suggestedParams = {
+        genesisHash,
+        genesisID,
         firstRound,
         lastRound,
+        fee,
+      };
+      const actualTxn = algosdk.makeAssetCreateTxnWithSuggestedParams(
+        addr,
         note,
-        genesisHash,
-        genesisID,
         total,
         decimals,
         defaultFrozen,
@@ -1141,6 +1161,7 @@ describe('Sign', () => {
         assetName,
         assetURL,
         assetMetadataHash,
+        suggestedParams,
         rekeyTo
       );
       assert.deepStrictEqual(expectedTxn, actualTxn);
@@ -1328,19 +1349,22 @@ describe('Sign', () => {
         reKeyTo: rekeyTo,
       };
       const expectedTxn = new algosdk.Transaction(o);
-      const actualTxn = algosdk.makeAssetConfigTxn(
-        addr,
-        fee,
+      const suggestedParams = {
+        genesisHash,
+        genesisID,
         firstRound,
         lastRound,
+        fee,
+      };
+      const actualTxn = algosdk.makeAssetConfigTxnWithSuggestedParams(
+        addr,
         note,
-        genesisHash,
-        genesisID,
         assetIndex,
         manager,
         reserve,
         freeze,
         clawback,
+        suggestedParams,
         true,
         rekeyTo
       );
@@ -1362,19 +1386,22 @@ describe('Sign', () => {
       const note = new Uint8Array([123, 12, 200]);
       let threw = false;
       try {
-        algosdk.makeAssetConfigTxn(
-          addr,
-          fee,
+        const suggestedParams = {
+          genesisHash,
+          genesisID,
           firstRound,
           lastRound,
+          fee,
+        };
+        algosdk.makeAssetConfigTxnWithSuggestedParams(
+          addr,
           note,
-          genesisHash,
-          genesisID,
           assetIndex,
           manager,
           reserve,
           freeze,
-          clawback
+          clawback,
+          suggestedParams
         );
       } catch {
         threw = true;
@@ -1406,15 +1433,18 @@ describe('Sign', () => {
         reKeyTo: rekeyTo,
       };
       const expectedTxn = new algosdk.Transaction(o);
-      const actualTxn = algosdk.makeAssetDestroyTxn(
-        addr,
-        fee,
+      const suggestedParams = {
+        genesisHash,
+        genesisID,
         firstRound,
         lastRound,
+        fee,
+      };
+      const actualTxn = algosdk.makeAssetDestroyTxnWithSuggestedParams(
+        addr,
         note,
-        genesisHash,
-        genesisID,
         assetIndex,
+        suggestedParams,
         rekeyTo
       );
       assert.deepStrictEqual(expectedTxn, actualTxn);
@@ -1453,19 +1483,23 @@ describe('Sign', () => {
         reKeyTo: rekeyTo,
       };
       const expectedTxn = new algosdk.Transaction(o);
-      const actualTxn = algosdk.makeAssetTransferTxn(
+      const suggestedParams = {
+        genesisHash,
+        genesisID,
+        firstRound,
+        lastRound,
+        fee,
+      };
+
+      const actualTxn = algosdk.makeAssetTransferTxnWithSuggestedParams(
         sender,
         recipient,
         closeRemainderTo,
         revocationTarget,
-        fee,
         amount,
-        firstRound,
-        lastRound,
         note,
-        genesisHash,
-        genesisID,
         assetIndex,
+        suggestedParams,
         rekeyTo
       );
       assert.deepStrictEqual(expectedTxn, actualTxn);
@@ -1499,17 +1533,21 @@ describe('Sign', () => {
         reKeyTo: rekeyTo,
       };
       const expectedTxn = new algosdk.Transaction(o);
-      const actualTxn = algosdk.makeAssetFreezeTxn(
-        addr,
-        fee,
+      const suggestedParams = {
+        genesisHash,
+        genesisID,
         firstRound,
         lastRound,
+        fee,
+      };
+
+      const actualTxn = algosdk.makeAssetFreezeTxnWithSuggestedParams(
+        addr,
         note,
-        genesisHash,
-        genesisID,
         assetIndex,
         freezeTarget,
         freezeState,
+        suggestedParams,
         rekeyTo
       );
       assert.deepStrictEqual(expectedTxn, actualTxn);
diff --git a/tests/7.AlgoSDK.js b/tests/7.AlgoSDK.js
index e8841c5..94686e9 100644
--- a/tests/7.AlgoSDK.js
+++ b/tests/7.AlgoSDK.js
@@ -39,17 +39,20 @@ describe('Algosdk (AKA end to end)', () => {
         'IDUTJEUIEVSMXTU4LGTJWZ2UE2E6TIODUKU6UW3FU3UKIQQ77RLUBBBFLA';
       const note = new Uint8Array(Buffer.from('6gAVR0Nsv5Y=', 'base64'));
       const from = to;
-      const txnAsObj = algosdk.makePaymentTxn(
+      const suggestedParams = {
+        genesisHash,
+        genesisID,
+        firstRound,
+        lastRound,
+        fee,
+      };
+      const txnAsObj = algosdk.makePaymentTxnWithSuggestedParams(
         from,
         to,
-        fee,
         amount,
         closeRemainderTo,
-        firstRound,
-        lastRound,
         note,
-        genesisHash,
-        genesisID
+        suggestedParams
       );
       const txnAsBuffer = algosdk.encodeUnsignedTransaction(txnAsObj);
       const txnAsObjRecovered = algosdk.decodeUnsignedTransaction(txnAsBuffer);
@@ -78,17 +81,20 @@ describe('Algosdk (AKA end to end)', () => {
         'IDUTJEUIEVSMXTU4LGTJWZ2UE2E6TIODUKU6UW3FU3UKIQQ77RLUBBBFLA';
       const note = new Uint8Array(Buffer.from('6gAVR0Nsv5Y=', 'base64'));
       const from = to;
-      const txnAsObj = algosdk.makePaymentTxn(
+      const suggestedParams = {
+        genesisHash,
+        genesisID,
+        firstRound,
+        lastRound,
+        fee,
+      };
+      const txnAsObj = algosdk.makePaymentTxnWithSuggestedParams(
         from,
         to,
-        fee,
         amount,
         closeRemainderTo,
-        firstRound,
-        lastRound,
         note,
-        genesisHash,
-        genesisID
+        suggestedParams
       );
       let sk =
         'advice pudding treat near rule blouse same whisper inner electric quit surface sunny dismiss leader blood seat clown cost exist hospital century reform able sponsor';
@@ -228,17 +234,20 @@ describe('Algosdk (AKA end to end)', () => {
       sk = algosdk.mnemonicToSecretKey(sk);
       const key = nacl.keyPairFromSecretKey(sk.sk);
       const from = algosdk.encodeAddress(key.publicKey);
-      const txn = algosdk.makePaymentTxn(
+      const suggestedParams = {
+        genesisHash,
+        genesisID,
+        firstRound,
+        lastRound,
+        fee,
+      };
+      const txn = algosdk.makePaymentTxnWithSuggestedParams(
         from,
         to,
-        fee,
         amount,
         closeRemainderTo,
-        firstRound,
-        lastRound,
         note,
-        genesisHash,
-        genesisID
+        suggestedParams
       );
       txn.addLease(lease, fee);
 
@@ -418,17 +427,20 @@ describe('Algosdk (AKA end to end)', () => {
         closeRemainderTo: closeRemainder,
         note,
       };
-      const oObj = algosdk.makePaymentTxn(
+      const suggestedParams = {
+        genesisHash,
+        genesisID,
+        firstRound,
+        lastRound,
+        fee,
+      };
+      const oObj = algosdk.makePaymentTxnWithSuggestedParams(
         fromAddr,
         toAddr,
-        fee,
         amount,
         closeRemainder,
-        firstRound,
-        lastRound,
         note,
-        genesisHash,
-        genesisID
+        suggestedParams
       );
 
       const oDictOutput = algosdk.signMultisigTransaction(oDict, params, sk);
@@ -819,14 +831,14 @@ describe('Algosdk (AKA end to end)', () => {
   describe('LogicSig', () => {
     it('should return valid logic sig object', () => {
       const program = Uint8Array.from([1, 32, 1, 1, 34]); // int 1
-      let lsig = algosdk.makeLogicSig(program);
+      let lsig = new algosdk.LogicSig(program);
       assert.equal(lsig.logic, program);
       assert.equal(lsig.args, undefined);
       assert.equal(lsig.sig, undefined);
       assert.equal(lsig.msig, undefined);
 
       const args = [Uint8Array.from('123'), Uint8Array.from('456')];
-      lsig = algosdk.makeLogicSig(program, args);
+      lsig = new algosdk.LogicSig(program, args);
       assert.equal(lsig.logic, program);
       assert.deepEqual(lsig.args, args);
     });
@@ -835,7 +847,7 @@ describe('Algosdk (AKA end to end)', () => {
     it('should work on valid program', () => {
       const program = Uint8Array.from([1, 32, 1, 1, 34]);
       const keys = algosdk.generateAccount();
-      const lsig = algosdk.makeLogicSig(program);
+      const lsig = new algosdk.LogicSig(program);
       lsig.sign(keys.sk);
       const verified = lsig.verify(algosdk.decodeAddress(keys.addr).publicKey);
       assert.equal(verified, true);
@@ -849,7 +861,7 @@ describe('Algosdk (AKA end to end)', () => {
   describe('Multisig logic sig', () => {
     it('should work on valid program', () => {
       const program = Uint8Array.from([1, 32, 1, 1, 34]);
-      const lsig = algosdk.makeLogicSig(program);
+      const lsig = new algosdk.LogicSig(program);
 
       const keys = algosdk.generateAccount();
       assert.throws(() => lsig.appendToMultisig(keys.sk), 'empty msig');
@@ -882,7 +894,7 @@ describe('Algosdk (AKA end to end)', () => {
       assert.equal(verified, true);
 
       // combine sig and msig
-      const lsigf = algosdk.makeLogicSig(program);
+      const lsigf = new algosdk.LogicSig(program);
       lsigf.sign(keys.sk);
       lsig.sig = lsigf.sig;
       verified = lsig.verify(msigPk);
@@ -932,7 +944,7 @@ describe('Algosdk (AKA end to end)', () => {
         Uint8Array.from([49, 50, 51]),
         Uint8Array.from([52, 53, 54]),
       ];
-      const lsig = algosdk.makeLogicSig(program, args);
+      const lsig = new algosdk.LogicSig(program, args);
       const sk = algosdk.mnemonicToSecretKey(mn);
       lsig.sign(sk.sk);
 
@@ -966,7 +978,7 @@ describe('Algosdk (AKA end to end)', () => {
       const keys = nacl.keyPairFromSeed(seed);
       const pk = keys.publicKey;
       const sk = keys.secretKey;
-      const addr = algosdk.makeLogicSig(prog).address();
+      const addr = new algosdk.LogicSig(prog).address();
       const sig1 = algosdk.tealSign(sk, data, addr);
       const sig2 = algosdk.tealSignFromProgram(sk, data, prog);
 
@@ -985,7 +997,10 @@ describe('Algosdk (AKA end to end)', () => {
   });
 
   describe('v2 Dryrun models', () => {
-    const schema = new algosdk.modelsv2.ApplicationStateSchema(5, 5);
+    const schema = new algosdk.modelsv2.ApplicationStateSchema({
+      numUint: 5,
+      numByteSlice: 5,
+    });
     const acc = new algosdk.modelsv2.Account({
       address: 'UAPJE355K7BG7RQVMTZOW7QW4ICZJEIC3RZGYG5LSHZ65K6LCNFPJDSR7M',
       amount: 5002280000000000,
@@ -1003,7 +1018,10 @@ describe('Algosdk (AKA end to end)', () => {
       localStateSchema: schema,
       globalStateSchema: schema,
     });
-    const app = new algosdk.modelsv2.Application(1380011588, params);
+    const app = new algosdk.modelsv2.Application({
+      id: 1380011588,
+      params,
+    });
     // make a raw txn
     const txn = {
       apsu: 'AiABASI=',
diff --git a/tests/8.LogicSig.ts b/tests/8.LogicSig.ts
index 5c35197..13609ac 100644
--- a/tests/8.LogicSig.ts
+++ b/tests/8.LogicSig.ts
@@ -1,7 +1,5 @@
 import assert from 'assert';
 import algosdk from '../src/index';
-import * as logic from '../src/logic/logic';
-import * as utils from '../src/utils/utils';
 
 const sampleAccount1 = algosdk.mnemonicToSecretKey(
   'auction inquiry lava second expand liberty glass involve ginger illness length room item discover ahead table doctor term tackle cement bonus profit right above catch'
@@ -29,7 +27,7 @@ describe('LogicSig', () => {
       const programHash =
         '6Z3C3LDVWGMX23BMSYMANACQOSINPFIRF77H7N3AWJZYV6OH6GWTJKVMXY';
       const pk = algosdk.decodeAddress(programHash).publicKey;
-      let lsig = algosdk.makeLogicSig(program);
+      let lsig = new algosdk.LogicSig(program);
       assert.strictEqual(lsig.logic, program);
       assert.strictEqual(lsig.args, undefined);
       assert.strictEqual(lsig.sig, undefined);
@@ -40,7 +38,7 @@ describe('LogicSig', () => {
       assert.strictEqual(verified, true);
 
       const args = [Uint8Array.from([1, 2, 3]), Uint8Array.from([4, 5, 6])];
-      lsig = algosdk.makeLogicSig(program, args);
+      lsig = new algosdk.LogicSig(program, args);
       assert.strictEqual(lsig.logic, program);
       assert.deepStrictEqual(lsig.args, args);
       assert.strictEqual(lsig.sig, undefined);
@@ -61,7 +59,7 @@ describe('LogicSig', () => {
       const pk = algosdk.decodeAddress(programHash).publicKey;
 
       program[3] = 2;
-      const lsig = algosdk.makeLogicSig(program);
+      const lsig = new algosdk.LogicSig(program);
       const verified = lsig.verify(pk);
       assert.strictEqual(verified, false);
     });
@@ -73,7 +71,7 @@ describe('LogicSig', () => {
       const programHash =
         '6Z3C3LDVWGMX23BMSYMANACQOSINPFIRF77H7N3AWJZYV6OH6GWTJKVMXY';
 
-      const lsig = algosdk.makeLogicSig(program);
+      const lsig = new algosdk.LogicSig(program);
       const address = lsig.address();
 
       assert.deepStrictEqual(address, programHash);
@@ -434,9 +432,7 @@ describe('signLogicSigTransaction', () => {
     'WTDCE2FEYM2VB5MKNXKLRSRDTSPR2EFTIGVH4GRW4PHGD6747GFJTBGT2A';
 
   function testSign(
-    lsigObject:
-      | ReturnType<typeof algosdk.makeLogicSig>
-      | algosdk.LogicSigAccount,
+    lsigObject: algosdk.LogicSig | algosdk.LogicSigAccount,
     sender: string,
     expected: { txID: string; blob: Uint8Array }
   ) {
@@ -462,7 +458,7 @@ describe('signLogicSigTransaction', () => {
 
   describe('with LogicSig', () => {
     describe('escrow', () => {
-      const lsig = algosdk.makeLogicSig(program, args);
+      const lsig = new algosdk.LogicSig(program, args);
 
       it('should match expected when sender is LogicSig address', () => {
         const sender = lsig.address();
@@ -497,7 +493,7 @@ describe('signLogicSigTransaction', () => {
       const account = algosdk.mnemonicToSecretKey(
         'olympic cricket tower model share zone grid twist sponsor avoid eight apology patient party success claim famous rapid donor pledge bomb mystery security ability often'
       );
-      const lsig = algosdk.makeLogicSig(program, args);
+      const lsig = new algosdk.LogicSig(program, args);
       lsig.sign(account.sk);
 
       it('should match expected when sender is LogicSig address', () => {
@@ -540,7 +536,7 @@ describe('signLogicSigTransaction', () => {
     });
 
     describe('multisig', () => {
-      const lsig = algosdk.makeLogicSig(program, args);
+      const lsig = new algosdk.LogicSig(program, args);
       lsig.sign(sampleAccount1.sk, sampleMultisigParams);
       lsig.appendToMultisig(sampleAccount2.sk);
 
@@ -679,7 +675,7 @@ describe('signLogicSigTransaction', () => {
   });
 
   it('should sign a raw transaction object', () => {
-    const lsig = algosdk.makeLogicSig(program);
+    const lsig = new algosdk.LogicSig(program);
 
     const from = lsig.address();
     const to = 'UCE2U2JC4O4ZR6W763GUQCG57HQCDZEUJY4J5I6VYY4HQZUJDF7AKZO5GM';
@@ -721,397 +717,3 @@ describe('signLogicSigTransaction', () => {
     assert.deepStrictEqual(actual, expected);
   });
 });
-
-describe('Program validation', () => {
-  describe('Varint', () => {
-    it('should parse binary data correctly', () => {
-      let data = Uint8Array.from([1]);
-      let [value, length] = logic.parseUvarint(data);
-      assert.strictEqual(length, 1);
-      assert.strictEqual(value, 1);
-
-      data = Uint8Array.from([123]);
-      [value, length] = logic.parseUvarint(data);
-      assert.strictEqual(length, 1);
-      assert.strictEqual(value, 123);
-
-      data = Uint8Array.from([200, 3]);
-      [value, length] = logic.parseUvarint(data);
-      assert.strictEqual(length, 2);
-      assert.strictEqual(value, 456);
-    });
-  });
-  describe('Const blocks', () => {
-    it('should parse int const block correctly', () => {
-      const data = Uint8Array.from([32, 5, 0, 1, 200, 3, 123, 2]);
-      const size = logic.checkIntConstBlock(data, 0);
-      assert.strictEqual(size, data.length);
-    });
-    it('should parse bytes const block correctly', () => {
-      const data = Uint8Array.from([
-        38,
-        2,
-        13,
-        49,
-        50,
-        51,
-        52,
-        53,
-        54,
-        55,
-        56,
-        57,
-        48,
-        49,
-        50,
-        51,
-        2,
-        1,
-        2,
-      ]);
-      const size = logic.checkByteConstBlock(data, 0);
-      assert.strictEqual(size, data.length);
-    });
-    it('should parse int push op correctly', () => {
-      const data = Uint8Array.from([0x81, 0x80, 0x80, 0x04]);
-      const size = logic.checkPushIntOp(data, 0);
-      assert.strictEqual(size, data.length);
-    });
-    it('should parse byte push op correctly', () => {
-      const data = Uint8Array.from([
-        0x80,
-        0x0b,
-        0x68,
-        0x65,
-        0x6c,
-        0x6c,
-        0x6f,
-        0x20,
-        0x77,
-        0x6f,
-        0x72,
-        0x6c,
-        0x64,
-      ]);
-      const size = logic.checkPushByteOp(data, 0);
-      assert.strictEqual(size, data.length);
-    });
-  });
-  describe('Program checker', () => {
-    it('should assess correct programs right', () => {
-      let program = Uint8Array.from([1, 32, 1, 1, 34]);
-      let result = logic.checkProgram(program);
-      assert.strictEqual(result, true);
-
-      const args = [Uint8Array.from([1, 2, 3])];
-
-      result = logic.checkProgram(program, args);
-      assert.strictEqual(result, true);
-
-      program = utils.concatArrays(program, new Array(10).fill(0x22));
-      result = logic.checkProgram(program, args);
-      assert.strictEqual(result, true);
-    });
-    it('should fail on long input', () => {
-      assert.throws(
-        () => (logic.checkProgram as any)(),
-        new Error('empty program')
-      );
-      let program = Uint8Array.from([1, 32, 1, 1, 34]);
-      assert.throws(
-        () => logic.checkProgram(program, [new Uint8Array(1000).fill(55)]),
-        new Error('program too long')
-      );
-
-      program = utils.concatArrays(program, new Uint8Array(1000).fill(34));
-      assert.throws(
-        () => logic.checkProgram(program),
-        new Error('program too long')
-      );
-    });
-    it('should fail on invalid program', () => {
-      const program = Uint8Array.from([1, 32, 1, 1, 34, 255]);
-      assert.throws(
-        () => logic.checkProgram(program),
-        new Error('invalid instruction')
-      );
-    });
-    it('should fail on invalid args', () => {
-      const program = Uint8Array.from([1, 32, 1, 1, 34]);
-      assert.throws(
-        () => logic.checkProgram(program, '123' as any),
-        new Error('invalid arguments')
-      );
-    });
-    it('should fail on costly program', () => {
-      let program = Uint8Array.from([1, 38, 1, 1, 1, 40, 2]); // byte 0x01 + keccak256
-      let result = logic.checkProgram(program);
-      assert.strictEqual(result, true);
-
-      // 10x keccak256 more is fine
-      program = utils.concatArrays(program, new Uint8Array(10).fill(2));
-      result = logic.checkProgram(program);
-      assert.strictEqual(result, true);
-
-      // 800x keccak256 more is too costly
-      program = utils.concatArrays(program, new Uint8Array(800).fill(2));
-      //  old versions
-      const oldVersions = [0x1, 0x2, 0x3];
-      let i;
-      for (i = 0; i < oldVersions.length; i++) {
-        program[0] = oldVersions[i];
-        assert.throws(
-          () => logic.checkProgram(program),
-          new Error('program too costly for version < 4. consider using v4.')
-        );
-      }
-      //  new versions
-      const newVersions = [0x4];
-      for (i = 0; i < newVersions.length; i++) {
-        program[0] = newVersions[i];
-        assert.ok(logic.checkProgram(program));
-      }
-    });
-    it('should support AVM v2 opcodes', () => {
-      assert.ok(logic.langspecEvalMaxVersion >= 2);
-      assert.ok(logic.langspecLogicSigVersion >= 2);
-
-      // balance
-      let program = Uint8Array.from([0x02, 0x20, 0x01, 0x00, 0x22, 0x60]); // int 0; balance
-      let result = logic.checkProgram(program);
-      assert.strictEqual(result, true);
-
-      // app_opted_in
-      program = Uint8Array.from([0x02, 0x20, 0x01, 0x00, 0x22, 0x22, 0x61]); // int 0; int 0; app_opted_in
-      result = logic.checkProgram(program);
-      assert.strictEqual(result, true);
-
-      // 800x keccak256 more is to costly
-      // prettier-ignore
-      program = Uint8Array.from([0x02, 0x20, 0x01, 0x00, 0x22, 0x22, 0x70, 0x00 ]); // int 0; int 0; asset_holding_get Balance
-      result = logic.checkProgram(program);
-      assert.strictEqual(result, true);
-    });
-    it('should support AVM v3 opcodes', () => {
-      assert.ok(logic.langspecEvalMaxVersion >= 3);
-      assert.ok(logic.langspecLogicSigVersion >= 3);
-
-      // min_balance
-      let program = Uint8Array.from([0x03, 0x20, 0x01, 0x00, 0x22, 0x78]); // int 0; min_balance
-      assert.ok(logic.checkProgram(program));
-
-      // pushbytes
-      program = Uint8Array.from([
-        0x03,
-        0x20,
-        0x01,
-        0x00,
-        0x22,
-        0x80,
-        0x02,
-        0x68,
-        0x69,
-        0x48,
-      ]); // int 0; pushbytes "hi"; pop
-      assert.ok(logic.checkProgram(program));
-
-      // pushint
-      program = Uint8Array.from([
-        0x03,
-        0x20,
-        0x01,
-        0x00,
-        0x22,
-        0x81,
-        0x01,
-        0x48,
-      ]); // int 0; pushint 1; pop
-      assert.ok(logic.checkProgram(program));
-
-      // swap
-      program = Uint8Array.from([
-        0x03,
-        0x20,
-        0x02,
-        0x00,
-        0x01,
-        0x22,
-        0x23,
-        0x4c,
-        0x48,
-      ]); // int 0; int 1; swap; pop
-      assert.ok(logic.checkProgram(program));
-    });
-    it('should support AVM v4 opcodes', () => {
-      assert.ok(logic.langspecEvalMaxVersion >= 4);
-
-      // divmodw
-      let program = Uint8Array.from([
-        0x04,
-        0x20,
-        0x03,
-        0x01,
-        0x00,
-        0x02,
-        0x22,
-        0x81,
-        0xd0,
-        0x0f,
-        0x23,
-        0x24,
-        0x1f,
-      ]); // int 1; pushint 2000; int 0; int 2; divmodw
-      assert.ok(logic.checkProgram(program));
-
-      // gloads i
-      program = Uint8Array.from([0x04, 0x20, 0x01, 0x00, 0x22, 0x3b, 0x00]); // int 0; gloads 0
-      assert.ok(logic.checkProgram(program));
-
-      // callsub
-      program = Uint8Array.from([
-        0x04,
-        0x20,
-        0x02,
-        0x01,
-        0x02,
-        0x22,
-        0x88,
-        0x00,
-        0x02,
-        0x23,
-        0x12,
-        0x49,
-      ]); // int 1; callsub double; int 2; ==; double: dup;
-      assert.ok(logic.checkProgram(program));
-
-      // b>=
-      program = Uint8Array.from([
-        0x04,
-        0x26,
-        0x02,
-        0x01,
-        0x11,
-        0x01,
-        0x10,
-        0x28,
-        0x29,
-        0xa7,
-      ]); // byte 0x11; byte 0x10; b>=
-      assert.ok(logic.checkProgram(program));
-
-      // b^
-      program = Uint8Array.from([
-        0x04,
-        0x26,
-        0x03,
-        0x01,
-        0x11,
-        0x01,
-        0x10,
-        0x01,
-        0x01,
-        0x28,
-        0x29,
-        0xad,
-        0x2a,
-        0x12,
-      ]); // byte 0x11; byte 0x10; b>=
-      assert.ok(logic.checkProgram(program));
-
-      // callsub, retsub
-      program = Uint8Array.from([
-        0x04,
-        0x20,
-        0x02,
-        0x01,
-        0x02,
-        0x22,
-        0x88,
-        0x00,
-        0x03,
-        0x23,
-        0x12,
-        0x43,
-        0x49,
-        0x08,
-        0x89,
-      ]); // int 1; callsub double; int 2; ==; return; double: dup; +; retsub;
-      assert.ok(logic.checkProgram(program));
-
-      // loop
-      program = Uint8Array.from([
-        0x04,
-        0x20,
-        0x04,
-        0x01,
-        0x02,
-        0x0a,
-        0x10,
-        0x22,
-        0x23,
-        0x0b,
-        0x49,
-        0x24,
-        0x0c,
-        0x40,
-        0xff,
-        0xf8,
-        0x25,
-        0x12,
-      ]); // int 1; loop: int 2; *; dup; int 10; <; bnz loop; int 16; ==
-      assert.ok(logic.checkProgram(program));
-    });
-    it('should support AVM v5 opcodes', () => {
-      assert.ok(logic.langspecEvalMaxVersion >= 5);
-
-      // itxn ops
-      let program = new Uint8Array(
-        Buffer.from('052001c0843db18101b21022b2083100b207b3b4082212', 'hex')
-      );
-      // itxn_begin; int pay; itxn_field TypeEnum; int 1000000; itxn_field Amount; txn Sender; itxn_field Receiver; itxn_submit; itxn Amount; int 1000000; ==
-      assert.ok(logic.checkProgram(program));
-
-      // ECDSA ops
-      program = new Uint8Array(
-        Buffer.from(
-          '058008746573746461746103802079bfa8245aeac0e714b7bd2b3252d03979e5e7a43cb039715a5f8109a7dd9ba180200753d317e54350d1d102289afbde3002add4529f10b9f7d3d223843985de62e0802103abfb5e6e331fb871e423f354e2bd78a384ef7cb07ac8bbf27d2dd1eca00e73c106000500',
-          'hex'
-        )
-      );
-      // byte "testdata"; sha512_256; byte 0x79bfa8245aeac0e714b7bd2b3252d03979e5e7a43cb039715a5f8109a7dd9ba1; byte 0x0753d317e54350d1d102289afbde3002add4529f10b9f7d3d223843985de62e0; byte 0x03abfb5e6e331fb871e423f354e2bd78a384ef7cb07ac8bbf27d2dd1eca00e73c1; ecdsa_pk_decompress Secp256k1; ecdsa_verify Secp256k1
-      assert.ok(logic.checkProgram(program));
-
-      // cover, uncover, log
-      program = new Uint8Array(
-        Buffer.from('058001618001628001634e024f025050b08101', 'hex')
-      );
-      // byte "a"; byte "b"; byte "c"; cover 2; uncover 2; concat; concat; log; int 1
-      assert.ok(logic.checkProgram(program));
-    });
-    it('should support AVM v6 opcodes', () => {
-      assert.ok(logic.langspecEvalMaxVersion >= 6);
-
-      // bsqrt op
-      let program = new Uint8Array(Buffer.from('068001909680010ca8', 'hex'));
-      // byte 0x90; bsqrt; byte 0x0c; b==
-      assert.ok(logic.checkProgram(program));
-
-      // divw op
-      program = new Uint8Array(
-        Buffer.from(
-          '06810981ecffffffffffffffff01810a9781feffffffffffffffff0112',
-          'hex'
-        )
-      );
-      //  int 9; int 18446744073709551596; int 10; divw; int 18446744073709551614; ==
-      assert.ok(logic.checkProgram(program));
-
-      // txn fields
-      program = new Uint8Array(
-        Buffer.from('06313f1581401233003e15810a1210', 'hex')
-      );
-      // txn StateProofPK; len; int 64; ==; gtxn 0 LastLog; len; int 10; ==; &&
-      assert.ok(logic.checkProgram(program));
-    });
-  });
-});
diff --git a/tests/9.Client.ts b/tests/9.Client.ts
index 7d0d0e1..f662cef 100644
--- a/tests/9.Client.ts
+++ b/tests/9.Client.ts
@@ -2,6 +2,7 @@ import assert from 'assert';
 import HTTPClient from '../src/client/client';
 import { URLTokenBaseHTTPClient } from '../src/client/urlTokenBaseHTTPClient';
 import IntDecoding from '../src/types/intDecoding';
+import AlgodClient from '../src/client/v2/algod/algod';
 import * as utils from '../src/utils/utils';
 
 describe('client', () => {
@@ -136,4 +137,29 @@ describe('client', () => {
       assert.throws(() => new HTTPClient({}, baseServer));
     });
   });
+  describe('AlgodClient construction', () => {
+    /* eslint-disable dot-notation */
+    const baseServer = 'http://localhost';
+    it('should not assign a bogus port', () => {
+      const client = new AlgodClient('', baseServer);
+      assert.strictEqual(client.c['bc']['baseURL']['port'], '');
+    });
+
+    it('should accept a port as an argument and assign it correctly', () => {
+      const client = new AlgodClient('', baseServer, 123);
+      assert.strictEqual(client.c['bc']['baseURL']['port'], '123');
+    });
+
+    it('should accept a port in the url assign it correctly', () => {
+      const client = new AlgodClient('', `${baseServer}:${123}`);
+      assert.strictEqual(client.c['bc']['baseURL']['port'], '123');
+    });
+
+    it('should override the port from the URL with the one specified in the argument', () => {
+      const client = new AlgodClient('', `${baseServer}:${123}`, 456);
+      assert.strictEqual(client.c['bc']['baseURL']['port'], '456');
+    });
+
+    /* eslint-disable dot-notation */
+  });
 });
diff --git a/tests/cucumber/steps/steps.js b/tests/cucumber/steps/steps.js
index a62f587..56af3f7 100644
--- a/tests/cucumber/steps/steps.js
+++ b/tests/cucumber/steps/steps.js
@@ -2724,7 +2724,7 @@ module.exports = function getSteps(options) {
       case 'compiled':
         txns = [
           {
-            lsig: algosdk.makeLogicSig(data),
+            lsig: new algosdk.LogicSig(data),
             txn: algoTxn,
           },
         ];
@@ -2736,7 +2736,11 @@ module.exports = function getSteps(options) {
           },
         ];
         sources = [
-          new algosdk.modelsv2.DryrunSource('lsig', data.toString('utf8'), 0),
+          new algosdk.modelsv2.DryrunSource({
+            fieldName: 'lsig',
+            source: data.toString('utf8'),
+            txnIndex: 0,
+          }),
         ];
         break;
       default:
@@ -2819,7 +2823,7 @@ module.exports = function getSteps(options) {
 
   Given('base64 encoded program {string}', function (programEncoded) {
     const program = Buffer.from(programEncoded, 'base64');
-    const lsig = algosdk.makeLogicSig(program);
+    const lsig = new algosdk.LogicSig(program);
     this.contractAddress = lsig.address();
   });