@algorandfoundation/algokit-utils 9.1.1-beta.2 → 9.1.1-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "**"
7
7
  ],
8
8
  "name": "@algorandfoundation/algokit-utils",
9
- "version": "9.1.1-beta.2",
9
+ "version": "9.1.1-beta.4",
10
10
  "private": false,
11
11
  "description": "A set of core Algorand utilities written in TypeScript and released via npm that make it easier to build solutions on Algorand.",
12
12
  "author": "Algorand Foundation",
@@ -7,6 +7,8 @@ import Indexer = algosdk.Indexer;
7
7
  */
8
8
  export declare class TransactionLogger {
9
9
  private _sentTransactionIds;
10
+ private _latestLastValidRound?;
11
+ private _pushTxn;
10
12
  /**
11
13
  * The list of transaction IDs that has been logged thus far.
12
14
  */
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var algosdk = require('algosdk');
4
+ var config = require('../config.js');
4
5
  var indexer = require('./indexer.js');
5
6
 
6
7
  var decodeSignedTransaction = algosdk.decodeSignedTransaction;
@@ -12,6 +13,13 @@ class TransactionLogger {
12
13
  constructor() {
13
14
  this._sentTransactionIds = [];
14
15
  }
16
+ _pushTxn(stxn) {
17
+ const decoded = decodeSignedTransaction(stxn);
18
+ if (decoded.txn.lastValid > (this._latestLastValidRound ?? BigInt(0))) {
19
+ this._latestLastValidRound = BigInt(decoded.txn.lastValid);
20
+ }
21
+ this._sentTransactionIds.push(decoded.txn.txID());
22
+ }
15
23
  /**
16
24
  * The list of transaction IDs that has been logged thus far.
17
25
  */
@@ -29,14 +37,10 @@ class TransactionLogger {
29
37
  */
30
38
  logRawTransaction(signedTransactions) {
31
39
  if (Array.isArray(signedTransactions)) {
32
- for (const stxn of signedTransactions) {
33
- const decoded = decodeSignedTransaction(stxn);
34
- this._sentTransactionIds.push(decoded.txn.txID());
35
- }
40
+ signedTransactions.forEach((stxn) => this._pushTxn(stxn));
36
41
  }
37
42
  else {
38
- const decoded = decodeSignedTransaction(signedTransactions);
39
- this._sentTransactionIds.push(decoded.txn.txID());
43
+ this._pushTxn(signedTransactions);
40
44
  }
41
45
  }
42
46
  /** Return a proxy that wraps the given Algodv2 with this transaction logger.
@@ -52,7 +56,22 @@ class TransactionLogger {
52
56
  if (this._sentTransactionIds.length === 0)
53
57
  return;
54
58
  const lastTxId = this._sentTransactionIds[this._sentTransactionIds.length - 1];
55
- await indexer.runWhenIndexerCaughtUp(() => indexer$1.lookupTransactionByID(lastTxId).do());
59
+ await indexer.runWhenIndexerCaughtUp(async () => {
60
+ try {
61
+ await indexer$1.lookupTransactionByID(lastTxId).do();
62
+ }
63
+ catch (e) {
64
+ // If the txid lookup failed, then try to look up the last valid round
65
+ // If that round exists, then we know indexer is caught up
66
+ if (this._latestLastValidRound) {
67
+ await indexer$1.lookupBlock(this._latestLastValidRound).do();
68
+ config.Config.getLogger().debug(`waitForIndexer has waited until the last valid round ${this._latestLastValidRound} was indexed, but did not find transaction ${lastTxId} in the indexer.`);
69
+ }
70
+ else {
71
+ throw e;
72
+ }
73
+ }
74
+ });
56
75
  }
57
76
  }
58
77
  class TransactionLoggingAlgodv2ProxyHandler {
@@ -1 +1 @@
1
- {"version":3,"file":"transaction-logger.js","sources":["../../src/testing/transaction-logger.ts"],"sourcesContent":["import algosdk from 'algosdk'\nimport { runWhenIndexerCaughtUp } from './indexer'\nimport Algodv2 = algosdk.Algodv2\nimport decodeSignedTransaction = algosdk.decodeSignedTransaction\nimport Indexer = algosdk.Indexer\n\n/**\n * Allows you to keep track of Algorand transaction IDs by wrapping an `Algodv2` in a proxy.\n * Useful for automated tests.\n */\nexport class TransactionLogger {\n private _sentTransactionIds: string[] = []\n\n /**\n * The list of transaction IDs that has been logged thus far.\n */\n get sentTransactionIds(): Readonly<string[]> {\n return this._sentTransactionIds\n }\n\n /**\n * Clear all logged IDs.\n */\n clear() {\n this._sentTransactionIds = []\n }\n\n /**\n * The method that captures raw transactions and stores the transaction IDs.\n */\n logRawTransaction(signedTransactions: Uint8Array | Uint8Array[]) {\n if (Array.isArray(signedTransactions)) {\n for (const stxn of signedTransactions) {\n const decoded = decodeSignedTransaction(stxn)\n this._sentTransactionIds.push(decoded.txn.txID())\n }\n } else {\n const decoded = decodeSignedTransaction(signedTransactions)\n this._sentTransactionIds.push(decoded.txn.txID())\n }\n }\n\n /** Return a proxy that wraps the given Algodv2 with this transaction logger.\n *\n * @param algod The `Algodv2` to wrap\n * @returns The wrapped `Algodv2`, any transactions sent using this algod instance will be logged by this transaction logger\n */\n capture(algod: Algodv2): Algodv2 {\n return new Proxy<Algodv2>(algod, new TransactionLoggingAlgodv2ProxyHandler(this))\n }\n\n /** Wait until all logged transactions IDs appear in the given `Indexer`. */\n async waitForIndexer(indexer: Indexer) {\n if (this._sentTransactionIds.length === 0) return\n const lastTxId = this._sentTransactionIds[this._sentTransactionIds.length - 1]\n await runWhenIndexerCaughtUp(() => indexer.lookupTransactionByID(lastTxId).do())\n }\n}\n\nclass TransactionLoggingAlgodv2ProxyHandler implements ProxyHandler<Algodv2> {\n private transactionLogger: TransactionLogger\n\n constructor(transactionLogger: TransactionLogger) {\n this.transactionLogger = transactionLogger\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n get(target: Algodv2, property: string | symbol, receiver: any) {\n if (property === 'sendRawTransaction') {\n return (stxOrStxs: Uint8Array | Uint8Array[]) => {\n this.transactionLogger.logRawTransaction(stxOrStxs)\n return target[property].call(receiver, stxOrStxs)\n }\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (target as any)[property]\n }\n}\n"],"names":["indexer","runWhenIndexerCaughtUp"],"mappings":";;;;;AAGA,IAAO,uBAAuB,GAAG,OAAO,CAAC,uBAAuB;AAGhE;;;AAGG;MACU,iBAAiB,CAAA;AAA9B,IAAA,WAAA,GAAA;QACU,IAAmB,CAAA,mBAAA,GAAa,EAAE;;AAE1C;;AAEG;AACH,IAAA,IAAI,kBAAkB,GAAA;QACpB,OAAO,IAAI,CAAC,mBAAmB;;AAGjC;;AAEG;IACH,KAAK,GAAA;AACH,QAAA,IAAI,CAAC,mBAAmB,GAAG,EAAE;;AAG/B;;AAEG;AACH,IAAA,iBAAiB,CAAC,kBAA6C,EAAA;AAC7D,QAAA,IAAI,KAAK,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE;AACrC,YAAA,KAAK,MAAM,IAAI,IAAI,kBAAkB,EAAE;AACrC,gBAAA,MAAM,OAAO,GAAG,uBAAuB,CAAC,IAAI,CAAC;AAC7C,gBAAA,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;;;aAE9C;AACL,YAAA,MAAM,OAAO,GAAG,uBAAuB,CAAC,kBAAkB,CAAC;AAC3D,YAAA,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;;;AAIrD;;;;AAIG;AACH,IAAA,OAAO,CAAC,KAAc,EAAA;QACpB,OAAO,IAAI,KAAK,CAAU,KAAK,EAAE,IAAI,qCAAqC,CAAC,IAAI,CAAC,CAAC;;;IAInF,MAAM,cAAc,CAACA,SAAgB,EAAA;AACnC,QAAA,IAAI,IAAI,CAAC,mBAAmB,CAAC,MAAM,KAAK,CAAC;YAAE;AAC3C,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAM,GAAG,CAAC,CAAC;AAC9E,QAAA,MAAMC,8BAAsB,CAAC,MAAMD,SAAO,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC;;AAEnF;AAED,MAAM,qCAAqC,CAAA;AAGzC,IAAA,WAAA,CAAY,iBAAoC,EAAA;AAC9C,QAAA,IAAI,CAAC,iBAAiB,GAAG,iBAAiB;;;AAI5C,IAAA,GAAG,CAAC,MAAe,EAAE,QAAyB,EAAE,QAAa,EAAA;AAC3D,QAAA,IAAI,QAAQ,KAAK,oBAAoB,EAAE;YACrC,OAAO,CAAC,SAAoC,KAAI;AAC9C,gBAAA,IAAI,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,SAAS,CAAC;gBACnD,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC;AACnD,aAAC;;;AAGH,QAAA,OAAQ,MAAc,CAAC,QAAQ,CAAC;;AAEnC;;;;"}
1
+ {"version":3,"file":"transaction-logger.js","sources":["../../src/testing/transaction-logger.ts"],"sourcesContent":["import algosdk from 'algosdk'\nimport { Config } from '../config'\nimport { runWhenIndexerCaughtUp } from './indexer'\nimport Algodv2 = algosdk.Algodv2\nimport decodeSignedTransaction = algosdk.decodeSignedTransaction\nimport Indexer = algosdk.Indexer\n\n/**\n * Allows you to keep track of Algorand transaction IDs by wrapping an `Algodv2` in a proxy.\n * Useful for automated tests.\n */\nexport class TransactionLogger {\n private _sentTransactionIds: string[] = []\n private _latestLastValidRound?: bigint\n\n private _pushTxn(stxn: Uint8Array) {\n const decoded = decodeSignedTransaction(stxn)\n if (decoded.txn.lastValid > (this._latestLastValidRound ?? BigInt(0))) {\n this._latestLastValidRound = BigInt(decoded.txn.lastValid)\n }\n this._sentTransactionIds.push(decoded.txn.txID())\n }\n\n /**\n * The list of transaction IDs that has been logged thus far.\n */\n get sentTransactionIds(): Readonly<string[]> {\n return this._sentTransactionIds\n }\n\n /**\n * Clear all logged IDs.\n */\n clear() {\n this._sentTransactionIds = []\n }\n\n /**\n * The method that captures raw transactions and stores the transaction IDs.\n */\n logRawTransaction(signedTransactions: Uint8Array | Uint8Array[]) {\n if (Array.isArray(signedTransactions)) {\n signedTransactions.forEach((stxn) => this._pushTxn(stxn))\n } else {\n this._pushTxn(signedTransactions)\n }\n }\n\n /** Return a proxy that wraps the given Algodv2 with this transaction logger.\n *\n * @param algod The `Algodv2` to wrap\n * @returns The wrapped `Algodv2`, any transactions sent using this algod instance will be logged by this transaction logger\n */\n capture(algod: Algodv2): Algodv2 {\n return new Proxy<Algodv2>(algod, new TransactionLoggingAlgodv2ProxyHandler(this))\n }\n\n /** Wait until all logged transactions IDs appear in the given `Indexer`. */\n async waitForIndexer(indexer: Indexer) {\n if (this._sentTransactionIds.length === 0) return\n const lastTxId = this._sentTransactionIds[this._sentTransactionIds.length - 1]\n await runWhenIndexerCaughtUp(async () => {\n try {\n await indexer.lookupTransactionByID(lastTxId).do()\n } catch (e) {\n // If the txid lookup failed, then try to look up the last valid round\n // If that round exists, then we know indexer is caught up\n if (this._latestLastValidRound) {\n await indexer.lookupBlock(this._latestLastValidRound).do()\n Config.getLogger().debug(\n `waitForIndexer has waited until the last valid round ${this._latestLastValidRound} was indexed, but did not find transaction ${lastTxId} in the indexer.`,\n )\n } else {\n throw e\n }\n }\n })\n }\n}\n\nclass TransactionLoggingAlgodv2ProxyHandler implements ProxyHandler<Algodv2> {\n private transactionLogger: TransactionLogger\n\n constructor(transactionLogger: TransactionLogger) {\n this.transactionLogger = transactionLogger\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n get(target: Algodv2, property: string | symbol, receiver: any) {\n if (property === 'sendRawTransaction') {\n return (stxOrStxs: Uint8Array | Uint8Array[]) => {\n this.transactionLogger.logRawTransaction(stxOrStxs)\n return target[property].call(receiver, stxOrStxs)\n }\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (target as any)[property]\n }\n}\n"],"names":["indexer","runWhenIndexerCaughtUp","Config"],"mappings":";;;;;;AAIA,IAAO,uBAAuB,GAAG,OAAO,CAAC,uBAAuB;AAGhE;;;AAGG;MACU,iBAAiB,CAAA;AAA9B,IAAA,WAAA,GAAA;QACU,IAAmB,CAAA,mBAAA,GAAa,EAAE;;AAGlC,IAAA,QAAQ,CAAC,IAAgB,EAAA;AAC/B,QAAA,MAAM,OAAO,GAAG,uBAAuB,CAAC,IAAI,CAAC;AAC7C,QAAA,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,IAAI,CAAC,qBAAqB,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;YACrE,IAAI,CAAC,qBAAqB,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC;;AAE5D,QAAA,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;;AAGnD;;AAEG;AACH,IAAA,IAAI,kBAAkB,GAAA;QACpB,OAAO,IAAI,CAAC,mBAAmB;;AAGjC;;AAEG;IACH,KAAK,GAAA;AACH,QAAA,IAAI,CAAC,mBAAmB,GAAG,EAAE;;AAG/B;;AAEG;AACH,IAAA,iBAAiB,CAAC,kBAA6C,EAAA;AAC7D,QAAA,IAAI,KAAK,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE;AACrC,YAAA,kBAAkB,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;;aACpD;AACL,YAAA,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC;;;AAIrC;;;;AAIG;AACH,IAAA,OAAO,CAAC,KAAc,EAAA;QACpB,OAAO,IAAI,KAAK,CAAU,KAAK,EAAE,IAAI,qCAAqC,CAAC,IAAI,CAAC,CAAC;;;IAInF,MAAM,cAAc,CAACA,SAAgB,EAAA;AACnC,QAAA,IAAI,IAAI,CAAC,mBAAmB,CAAC,MAAM,KAAK,CAAC;YAAE;AAC3C,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAM,GAAG,CAAC,CAAC;AAC9E,QAAA,MAAMC,8BAAsB,CAAC,YAAW;AACtC,YAAA,IAAI;gBACF,MAAMD,SAAO,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE;;YAClD,OAAO,CAAC,EAAE;;;AAGV,gBAAA,IAAI,IAAI,CAAC,qBAAqB,EAAE;oBAC9B,MAAMA,SAAO,CAAC,WAAW,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,EAAE,EAAE;AAC1D,oBAAAE,aAAM,CAAC,SAAS,EAAE,CAAC,KAAK,CACtB,CAAA,qDAAA,EAAwD,IAAI,CAAC,qBAAqB,CAAA,2CAAA,EAA8C,QAAQ,CAAA,gBAAA,CAAkB,CAC3J;;qBACI;AACL,oBAAA,MAAM,CAAC;;;AAGb,SAAC,CAAC;;AAEL;AAED,MAAM,qCAAqC,CAAA;AAGzC,IAAA,WAAA,CAAY,iBAAoC,EAAA;AAC9C,QAAA,IAAI,CAAC,iBAAiB,GAAG,iBAAiB;;;AAI5C,IAAA,GAAG,CAAC,MAAe,EAAE,QAAyB,EAAE,QAAa,EAAA;AAC3D,QAAA,IAAI,QAAQ,KAAK,oBAAoB,EAAE;YACrC,OAAO,CAAC,SAAoC,KAAI;AAC9C,gBAAA,IAAI,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,SAAS,CAAC;gBACnD,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC;AACnD,aAAC;;;AAGH,QAAA,OAAQ,MAAc,CAAC,QAAQ,CAAC;;AAEnC;;;;"}
@@ -1,4 +1,5 @@
1
1
  import algosdk from 'algosdk';
2
+ import { Config } from '../config.mjs';
2
3
  import { runWhenIndexerCaughtUp } from './indexer.mjs';
3
4
 
4
5
  var decodeSignedTransaction = algosdk.decodeSignedTransaction;
@@ -10,6 +11,13 @@ class TransactionLogger {
10
11
  constructor() {
11
12
  this._sentTransactionIds = [];
12
13
  }
14
+ _pushTxn(stxn) {
15
+ const decoded = decodeSignedTransaction(stxn);
16
+ if (decoded.txn.lastValid > (this._latestLastValidRound ?? BigInt(0))) {
17
+ this._latestLastValidRound = BigInt(decoded.txn.lastValid);
18
+ }
19
+ this._sentTransactionIds.push(decoded.txn.txID());
20
+ }
13
21
  /**
14
22
  * The list of transaction IDs that has been logged thus far.
15
23
  */
@@ -27,14 +35,10 @@ class TransactionLogger {
27
35
  */
28
36
  logRawTransaction(signedTransactions) {
29
37
  if (Array.isArray(signedTransactions)) {
30
- for (const stxn of signedTransactions) {
31
- const decoded = decodeSignedTransaction(stxn);
32
- this._sentTransactionIds.push(decoded.txn.txID());
33
- }
38
+ signedTransactions.forEach((stxn) => this._pushTxn(stxn));
34
39
  }
35
40
  else {
36
- const decoded = decodeSignedTransaction(signedTransactions);
37
- this._sentTransactionIds.push(decoded.txn.txID());
41
+ this._pushTxn(signedTransactions);
38
42
  }
39
43
  }
40
44
  /** Return a proxy that wraps the given Algodv2 with this transaction logger.
@@ -50,7 +54,22 @@ class TransactionLogger {
50
54
  if (this._sentTransactionIds.length === 0)
51
55
  return;
52
56
  const lastTxId = this._sentTransactionIds[this._sentTransactionIds.length - 1];
53
- await runWhenIndexerCaughtUp(() => indexer.lookupTransactionByID(lastTxId).do());
57
+ await runWhenIndexerCaughtUp(async () => {
58
+ try {
59
+ await indexer.lookupTransactionByID(lastTxId).do();
60
+ }
61
+ catch (e) {
62
+ // If the txid lookup failed, then try to look up the last valid round
63
+ // If that round exists, then we know indexer is caught up
64
+ if (this._latestLastValidRound) {
65
+ await indexer.lookupBlock(this._latestLastValidRound).do();
66
+ Config.getLogger().debug(`waitForIndexer has waited until the last valid round ${this._latestLastValidRound} was indexed, but did not find transaction ${lastTxId} in the indexer.`);
67
+ }
68
+ else {
69
+ throw e;
70
+ }
71
+ }
72
+ });
54
73
  }
55
74
  }
56
75
  class TransactionLoggingAlgodv2ProxyHandler {
@@ -1 +1 @@
1
- {"version":3,"file":"transaction-logger.mjs","sources":["../../src/testing/transaction-logger.ts"],"sourcesContent":["import algosdk from 'algosdk'\nimport { runWhenIndexerCaughtUp } from './indexer'\nimport Algodv2 = algosdk.Algodv2\nimport decodeSignedTransaction = algosdk.decodeSignedTransaction\nimport Indexer = algosdk.Indexer\n\n/**\n * Allows you to keep track of Algorand transaction IDs by wrapping an `Algodv2` in a proxy.\n * Useful for automated tests.\n */\nexport class TransactionLogger {\n private _sentTransactionIds: string[] = []\n\n /**\n * The list of transaction IDs that has been logged thus far.\n */\n get sentTransactionIds(): Readonly<string[]> {\n return this._sentTransactionIds\n }\n\n /**\n * Clear all logged IDs.\n */\n clear() {\n this._sentTransactionIds = []\n }\n\n /**\n * The method that captures raw transactions and stores the transaction IDs.\n */\n logRawTransaction(signedTransactions: Uint8Array | Uint8Array[]) {\n if (Array.isArray(signedTransactions)) {\n for (const stxn of signedTransactions) {\n const decoded = decodeSignedTransaction(stxn)\n this._sentTransactionIds.push(decoded.txn.txID())\n }\n } else {\n const decoded = decodeSignedTransaction(signedTransactions)\n this._sentTransactionIds.push(decoded.txn.txID())\n }\n }\n\n /** Return a proxy that wraps the given Algodv2 with this transaction logger.\n *\n * @param algod The `Algodv2` to wrap\n * @returns The wrapped `Algodv2`, any transactions sent using this algod instance will be logged by this transaction logger\n */\n capture(algod: Algodv2): Algodv2 {\n return new Proxy<Algodv2>(algod, new TransactionLoggingAlgodv2ProxyHandler(this))\n }\n\n /** Wait until all logged transactions IDs appear in the given `Indexer`. */\n async waitForIndexer(indexer: Indexer) {\n if (this._sentTransactionIds.length === 0) return\n const lastTxId = this._sentTransactionIds[this._sentTransactionIds.length - 1]\n await runWhenIndexerCaughtUp(() => indexer.lookupTransactionByID(lastTxId).do())\n }\n}\n\nclass TransactionLoggingAlgodv2ProxyHandler implements ProxyHandler<Algodv2> {\n private transactionLogger: TransactionLogger\n\n constructor(transactionLogger: TransactionLogger) {\n this.transactionLogger = transactionLogger\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n get(target: Algodv2, property: string | symbol, receiver: any) {\n if (property === 'sendRawTransaction') {\n return (stxOrStxs: Uint8Array | Uint8Array[]) => {\n this.transactionLogger.logRawTransaction(stxOrStxs)\n return target[property].call(receiver, stxOrStxs)\n }\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (target as any)[property]\n }\n}\n"],"names":[],"mappings":";;;AAGA,IAAO,uBAAuB,GAAG,OAAO,CAAC,uBAAuB;AAGhE;;;AAGG;MACU,iBAAiB,CAAA;AAA9B,IAAA,WAAA,GAAA;QACU,IAAmB,CAAA,mBAAA,GAAa,EAAE;;AAE1C;;AAEG;AACH,IAAA,IAAI,kBAAkB,GAAA;QACpB,OAAO,IAAI,CAAC,mBAAmB;;AAGjC;;AAEG;IACH,KAAK,GAAA;AACH,QAAA,IAAI,CAAC,mBAAmB,GAAG,EAAE;;AAG/B;;AAEG;AACH,IAAA,iBAAiB,CAAC,kBAA6C,EAAA;AAC7D,QAAA,IAAI,KAAK,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE;AACrC,YAAA,KAAK,MAAM,IAAI,IAAI,kBAAkB,EAAE;AACrC,gBAAA,MAAM,OAAO,GAAG,uBAAuB,CAAC,IAAI,CAAC;AAC7C,gBAAA,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;;;aAE9C;AACL,YAAA,MAAM,OAAO,GAAG,uBAAuB,CAAC,kBAAkB,CAAC;AAC3D,YAAA,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;;;AAIrD;;;;AAIG;AACH,IAAA,OAAO,CAAC,KAAc,EAAA;QACpB,OAAO,IAAI,KAAK,CAAU,KAAK,EAAE,IAAI,qCAAqC,CAAC,IAAI,CAAC,CAAC;;;IAInF,MAAM,cAAc,CAAC,OAAgB,EAAA;AACnC,QAAA,IAAI,IAAI,CAAC,mBAAmB,CAAC,MAAM,KAAK,CAAC;YAAE;AAC3C,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAM,GAAG,CAAC,CAAC;AAC9E,QAAA,MAAM,sBAAsB,CAAC,MAAM,OAAO,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC;;AAEnF;AAED,MAAM,qCAAqC,CAAA;AAGzC,IAAA,WAAA,CAAY,iBAAoC,EAAA;AAC9C,QAAA,IAAI,CAAC,iBAAiB,GAAG,iBAAiB;;;AAI5C,IAAA,GAAG,CAAC,MAAe,EAAE,QAAyB,EAAE,QAAa,EAAA;AAC3D,QAAA,IAAI,QAAQ,KAAK,oBAAoB,EAAE;YACrC,OAAO,CAAC,SAAoC,KAAI;AAC9C,gBAAA,IAAI,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,SAAS,CAAC;gBACnD,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC;AACnD,aAAC;;;AAGH,QAAA,OAAQ,MAAc,CAAC,QAAQ,CAAC;;AAEnC;;;;"}
1
+ {"version":3,"file":"transaction-logger.mjs","sources":["../../src/testing/transaction-logger.ts"],"sourcesContent":["import algosdk from 'algosdk'\nimport { Config } from '../config'\nimport { runWhenIndexerCaughtUp } from './indexer'\nimport Algodv2 = algosdk.Algodv2\nimport decodeSignedTransaction = algosdk.decodeSignedTransaction\nimport Indexer = algosdk.Indexer\n\n/**\n * Allows you to keep track of Algorand transaction IDs by wrapping an `Algodv2` in a proxy.\n * Useful for automated tests.\n */\nexport class TransactionLogger {\n private _sentTransactionIds: string[] = []\n private _latestLastValidRound?: bigint\n\n private _pushTxn(stxn: Uint8Array) {\n const decoded = decodeSignedTransaction(stxn)\n if (decoded.txn.lastValid > (this._latestLastValidRound ?? BigInt(0))) {\n this._latestLastValidRound = BigInt(decoded.txn.lastValid)\n }\n this._sentTransactionIds.push(decoded.txn.txID())\n }\n\n /**\n * The list of transaction IDs that has been logged thus far.\n */\n get sentTransactionIds(): Readonly<string[]> {\n return this._sentTransactionIds\n }\n\n /**\n * Clear all logged IDs.\n */\n clear() {\n this._sentTransactionIds = []\n }\n\n /**\n * The method that captures raw transactions and stores the transaction IDs.\n */\n logRawTransaction(signedTransactions: Uint8Array | Uint8Array[]) {\n if (Array.isArray(signedTransactions)) {\n signedTransactions.forEach((stxn) => this._pushTxn(stxn))\n } else {\n this._pushTxn(signedTransactions)\n }\n }\n\n /** Return a proxy that wraps the given Algodv2 with this transaction logger.\n *\n * @param algod The `Algodv2` to wrap\n * @returns The wrapped `Algodv2`, any transactions sent using this algod instance will be logged by this transaction logger\n */\n capture(algod: Algodv2): Algodv2 {\n return new Proxy<Algodv2>(algod, new TransactionLoggingAlgodv2ProxyHandler(this))\n }\n\n /** Wait until all logged transactions IDs appear in the given `Indexer`. */\n async waitForIndexer(indexer: Indexer) {\n if (this._sentTransactionIds.length === 0) return\n const lastTxId = this._sentTransactionIds[this._sentTransactionIds.length - 1]\n await runWhenIndexerCaughtUp(async () => {\n try {\n await indexer.lookupTransactionByID(lastTxId).do()\n } catch (e) {\n // If the txid lookup failed, then try to look up the last valid round\n // If that round exists, then we know indexer is caught up\n if (this._latestLastValidRound) {\n await indexer.lookupBlock(this._latestLastValidRound).do()\n Config.getLogger().debug(\n `waitForIndexer has waited until the last valid round ${this._latestLastValidRound} was indexed, but did not find transaction ${lastTxId} in the indexer.`,\n )\n } else {\n throw e\n }\n }\n })\n }\n}\n\nclass TransactionLoggingAlgodv2ProxyHandler implements ProxyHandler<Algodv2> {\n private transactionLogger: TransactionLogger\n\n constructor(transactionLogger: TransactionLogger) {\n this.transactionLogger = transactionLogger\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n get(target: Algodv2, property: string | symbol, receiver: any) {\n if (property === 'sendRawTransaction') {\n return (stxOrStxs: Uint8Array | Uint8Array[]) => {\n this.transactionLogger.logRawTransaction(stxOrStxs)\n return target[property].call(receiver, stxOrStxs)\n }\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (target as any)[property]\n }\n}\n"],"names":[],"mappings":";;;;AAIA,IAAO,uBAAuB,GAAG,OAAO,CAAC,uBAAuB;AAGhE;;;AAGG;MACU,iBAAiB,CAAA;AAA9B,IAAA,WAAA,GAAA;QACU,IAAmB,CAAA,mBAAA,GAAa,EAAE;;AAGlC,IAAA,QAAQ,CAAC,IAAgB,EAAA;AAC/B,QAAA,MAAM,OAAO,GAAG,uBAAuB,CAAC,IAAI,CAAC;AAC7C,QAAA,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,IAAI,CAAC,qBAAqB,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;YACrE,IAAI,CAAC,qBAAqB,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC;;AAE5D,QAAA,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;;AAGnD;;AAEG;AACH,IAAA,IAAI,kBAAkB,GAAA;QACpB,OAAO,IAAI,CAAC,mBAAmB;;AAGjC;;AAEG;IACH,KAAK,GAAA;AACH,QAAA,IAAI,CAAC,mBAAmB,GAAG,EAAE;;AAG/B;;AAEG;AACH,IAAA,iBAAiB,CAAC,kBAA6C,EAAA;AAC7D,QAAA,IAAI,KAAK,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE;AACrC,YAAA,kBAAkB,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;;aACpD;AACL,YAAA,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC;;;AAIrC;;;;AAIG;AACH,IAAA,OAAO,CAAC,KAAc,EAAA;QACpB,OAAO,IAAI,KAAK,CAAU,KAAK,EAAE,IAAI,qCAAqC,CAAC,IAAI,CAAC,CAAC;;;IAInF,MAAM,cAAc,CAAC,OAAgB,EAAA;AACnC,QAAA,IAAI,IAAI,CAAC,mBAAmB,CAAC,MAAM,KAAK,CAAC;YAAE;AAC3C,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAM,GAAG,CAAC,CAAC;AAC9E,QAAA,MAAM,sBAAsB,CAAC,YAAW;AACtC,YAAA,IAAI;gBACF,MAAM,OAAO,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE;;YAClD,OAAO,CAAC,EAAE;;;AAGV,gBAAA,IAAI,IAAI,CAAC,qBAAqB,EAAE;oBAC9B,MAAM,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,EAAE,EAAE;AAC1D,oBAAA,MAAM,CAAC,SAAS,EAAE,CAAC,KAAK,CACtB,CAAA,qDAAA,EAAwD,IAAI,CAAC,qBAAqB,CAAA,2CAAA,EAA8C,QAAQ,CAAA,gBAAA,CAAkB,CAC3J;;qBACI;AACL,oBAAA,MAAM,CAAC;;;AAGb,SAAC,CAAC;;AAEL;AAED,MAAM,qCAAqC,CAAA;AAGzC,IAAA,WAAA,CAAY,iBAAoC,EAAA;AAC9C,QAAA,IAAI,CAAC,iBAAiB,GAAG,iBAAiB;;;AAI5C,IAAA,GAAG,CAAC,MAAe,EAAE,QAAyB,EAAE,QAAa,EAAA;AAC3D,QAAA,IAAI,QAAQ,KAAK,oBAAoB,EAAE;YACrC,OAAO,CAAC,SAAoC,KAAI;AAC9C,gBAAA,IAAI,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,SAAS,CAAC;gBACnD,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC;AACnD,aAAC;;;AAGH,QAAA,OAAQ,MAAc,CAAC,QAAQ,CAAC;;AAEnC;;;;"}
@@ -1,4 +1,4 @@
1
- import algosdk from 'algosdk';
1
+ import algosdk, { ABIReturnType } from 'algosdk';
2
2
  import { AlgoAmount } from '../types/amount';
3
3
  import { ABIReturn } from '../types/app';
4
4
  import { AdditionalAtomicTransactionComposerContext, AtomicTransactionComposerToSend, SendAtomicTransactionComposerResults, SendParams, SendTransactionFrom, SendTransactionParams, SendTransactionResult, TransactionGroupToSend, TransactionNote, TransactionToSign } from '../types/transaction';
@@ -144,7 +144,7 @@ export declare const sendAtomicTransactionComposer: (atcSend: AtomicTransactionC
144
144
  * Converts `bigint`'s for Uint's < 64 to `number` for easier use.
145
145
  * @param result The `ABIReturn`
146
146
  */
147
- export declare function getABIReturnValue(result: algosdk.ABIResult): ABIReturn;
147
+ export declare function getABIReturnValue(result: algosdk.ABIResult, type: ABIReturnType): ABIReturn;
148
148
  /**
149
149
  * @deprecated Use `TransactionComposer` (`algorand.newGroup()`) or `AtomicTransactionComposer` to construct and send group transactions instead.
150
150
  *
@@ -679,12 +679,13 @@ const sendAtomicTransactionComposer = async function (atcSend, algod) {
679
679
  if (!sendParams?.skipWaiting) {
680
680
  confirmations = await Promise.all(transactionsToSend.map(async (t) => await algod.pendingTransactionInformation(t.txID()).do()));
681
681
  }
682
+ const methodCalls = [...atc['methodCalls'].values()];
682
683
  return {
683
684
  groupId,
684
685
  confirmations,
685
686
  txIds: transactionsToSend.map((t) => t.txID()),
686
687
  transactions: transactionsToSend,
687
- returns: result.methodResults.map(getABIReturnValue),
688
+ returns: result.methodResults.map((r, i) => getABIReturnValue(r, methodCalls[i].returns.type)),
688
689
  };
689
690
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
690
691
  }
@@ -756,19 +757,20 @@ const convertABIDecodedBigIntToNumber = (value, type) => {
756
757
  * Converts `bigint`'s for Uint's < 64 to `number` for easier use.
757
758
  * @param result The `ABIReturn`
758
759
  */
759
- function getABIReturnValue(result) {
760
+ function getABIReturnValue(result, type) {
760
761
  if (result.decodeError) {
761
762
  return {
762
763
  decodeError: result.decodeError,
763
764
  };
764
765
  }
766
+ const returnValue = util.convertAbiByteArrays(result.returnValue !== undefined && result.method.returns.type !== 'void'
767
+ ? convertABIDecodedBigIntToNumber(result.returnValue, result.method.returns.type)
768
+ : result.returnValue, type);
765
769
  return {
766
770
  method: result.method,
767
771
  rawReturnValue: result.rawReturnValue,
768
772
  decodeError: undefined,
769
- returnValue: result.returnValue !== undefined && result.method.returns.type !== 'void'
770
- ? convertABIDecodedBigIntToNumber(result.returnValue, result.method.returns.type)
771
- : result.returnValue,
773
+ returnValue,
772
774
  };
773
775
  }
774
776
  /**