@algorandfoundation/algokit-utils 9.1.2 → 9.2.0-beta.10

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.
Files changed (47) hide show
  1. package/app.d.ts +1 -1
  2. package/package.json +2 -2
  3. package/testing/fixtures/algorand-fixture.d.ts +3 -3
  4. package/testing/fixtures/algorand-fixture.js.map +1 -1
  5. package/testing/fixtures/algorand-fixture.mjs.map +1 -1
  6. package/transaction/legacy-bridge.d.ts +1 -1
  7. package/transaction/transaction.d.ts +1 -1
  8. package/transaction/transaction.js +66 -26
  9. package/transaction/transaction.js.map +1 -1
  10. package/transaction/transaction.mjs +66 -26
  11. package/transaction/transaction.mjs.map +1 -1
  12. package/types/algorand-client-transaction-creator.d.ts +20 -0
  13. package/types/algorand-client-transaction-creator.js +16 -0
  14. package/types/algorand-client-transaction-creator.js.map +1 -1
  15. package/types/algorand-client-transaction-creator.mjs +16 -0
  16. package/types/algorand-client-transaction-creator.mjs.map +1 -1
  17. package/types/algorand-client-transaction-sender.d.ts +116 -0
  18. package/types/algorand-client-transaction-sender.js +16 -0
  19. package/types/algorand-client-transaction-sender.js.map +1 -1
  20. package/types/algorand-client-transaction-sender.mjs +16 -0
  21. package/types/algorand-client-transaction-sender.mjs.map +1 -1
  22. package/types/app-client.d.ts +74 -0
  23. package/types/app-client.js +4 -1
  24. package/types/app-client.js.map +1 -1
  25. package/types/app-client.mjs +4 -1
  26. package/types/app-client.mjs.map +1 -1
  27. package/types/app-deployer.js +3 -3
  28. package/types/app-deployer.js.map +1 -1
  29. package/types/app-deployer.mjs +3 -3
  30. package/types/app-deployer.mjs.map +1 -1
  31. package/types/app-factory.d.ts +36 -0
  32. package/types/app-manager.d.ts +37 -0
  33. package/types/app-manager.js +1 -0
  34. package/types/app-manager.js.map +1 -1
  35. package/types/app-manager.mjs +1 -0
  36. package/types/app-manager.mjs.map +1 -1
  37. package/types/composer.d.ts +21 -1
  38. package/types/composer.js +53 -2
  39. package/types/composer.js.map +1 -1
  40. package/types/composer.mjs +53 -2
  41. package/types/composer.mjs.map +1 -1
  42. package/types/kmd-account-manager.d.ts +1 -0
  43. package/types/kmd-account-manager.js +33 -14
  44. package/types/kmd-account-manager.js.map +1 -1
  45. package/types/kmd-account-manager.mjs +33 -14
  46. package/types/kmd-account-manager.mjs.map +1 -1
  47. package/types/testing.d.ts +2 -2
package/app.d.ts CHANGED
@@ -164,7 +164,7 @@ export declare function getAppArgsForABICall(args: ABIAppCallArgs, from: SendTra
164
164
  appForeignApps: number[] | undefined;
165
165
  appForeignAssets: number[] | undefined;
166
166
  appAccounts: string[] | undefined;
167
- methodArgs: (string | number | bigint | boolean | Uint8Array | algosdk.ABIValue[] | algosdk.TransactionWithSigner)[];
167
+ methodArgs: (string | number | bigint | boolean | algosdk.Address | Uint8Array | algosdk.ABIValue[] | algosdk.TransactionWithSigner)[];
168
168
  rekeyTo: string | undefined;
169
169
  }>;
170
170
  /**
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "**"
7
7
  ],
8
8
  "name": "@algorandfoundation/algokit-utils",
9
- "version": "9.1.2",
9
+ "version": "9.2.0-beta.10",
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",
@@ -42,6 +42,6 @@
42
42
  "buffer": "^6.0.3"
43
43
  },
44
44
  "peerDependencies": {
45
- "algosdk": "^3.0.0"
45
+ "algosdk": "^3.5.2"
46
46
  }
47
47
  }
@@ -12,7 +12,7 @@ import { AlgorandFixture, AlgorandFixtureConfig } from '../../types/testing';
12
12
  * ```typescript
13
13
  * const fixture = algorandFixture()
14
14
  *
15
- * beforeEach(fixture.newScope, 10_000)
15
+ * beforeEach(fixture.newScope)
16
16
  *
17
17
  * test('My test', async () => {
18
18
  * const {algod, indexer, testAccount, ...} = fixture.context
@@ -24,7 +24,7 @@ import { AlgorandFixture, AlgorandFixtureConfig } from '../../types/testing';
24
24
  * ```typescript
25
25
  * const fixture = algorandFixture()
26
26
  *
27
- * beforeAll(fixture.newScope, 10_000)
27
+ * beforeAll(fixture.newScope)
28
28
  *
29
29
  * test('My test', async () => {
30
30
  * const {algod, indexer, testAccount, ...} = fixture.context
@@ -39,7 +39,7 @@ import { AlgorandFixture, AlgorandFixtureConfig } from '../../types/testing';
39
39
  * // ...
40
40
  * })
41
41
  *
42
- * beforeEach(fixture.newScope, 10_000)
42
+ * beforeEach(fixture.newScope)
43
43
  *
44
44
  * test('My test', async () => {
45
45
  * const {algod, indexer, testAccount, ...} = fixture.context
@@ -1 +1 @@
1
- {"version":3,"file":"algorand-fixture.js","sources":["../../../src/testing/fixtures/algorand-fixture.ts"],"sourcesContent":["import { algos, Config } from '../../'\nimport { AlgorandClient } from '../../types/algorand-client'\nimport { ClientManager } from '../../types/client-manager'\nimport { AlgoConfig } from '../../types/network-client'\nimport { AlgorandFixture, AlgorandFixtureConfig, AlgorandTestAutomationContext, GetTestAccountParams } from '../../types/testing'\nimport { getTestAccount } from '../account'\nimport { runWhenIndexerCaughtUp } from '../indexer'\nimport { TransactionLogger } from '../transaction-logger'\n\n/**\n * Creates a test fixture for automated testing against Algorand.\n * By default it tests against an environment variable specified client\n * if the standard environment variables are specified, otherwise against\n * a default LocalNet instance, but you can pass in an algod, indexer\n * and/or kmd (or their respective config) if you want to test against\n * an explicitly defined network.\n *\n * @example No config (per-test isolation)\n * ```typescript\n * const fixture = algorandFixture()\n *\n * beforeEach(fixture.newScope, 10_000)\n *\n * test('My test', async () => {\n * const {algod, indexer, testAccount, ...} = fixture.context\n * // test things...\n * })\n * ```\n *\n * @example No config (test suite isolation)\n * ```typescript\n * const fixture = algorandFixture()\n *\n * beforeAll(fixture.newScope, 10_000)\n *\n * test('My test', async () => {\n * const {algod, indexer, testAccount, ...} = fixture.context\n * // test things...\n * })\n * ```\n *\n * @example With config\n * ```typescript\n * const fixture = algorandFixture({\n * algod: new Algodv2('localhost', 12345, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),\n * // ...\n * })\n *\n * beforeEach(fixture.newScope, 10_000)\n *\n * test('My test', async () => {\n * const {algod, indexer, testAccount, ...} = fixture.context\n * // test things...\n * })\n * ```\n *\n * @param fixtureConfig The fixture configuration\n * @returns The fixture\n */\nexport function algorandFixture(fixtureConfig?: AlgorandFixtureConfig): AlgorandFixture\n\n/**\n * @deprecated Config can be passed in directly to fixture config now.\n *\n * Creates a test fixture for automated testing against Algorand.\n * By default it tests against an environment variable specified client\n * if the standard environment variables are specified, otherwise against\n * a default LocalNet instance, but you can pass in an algod, indexer\n * and/or kmd if you want to test against an explicitly defined network.\n *\n * @param fixtureConfig The fixture configuration\n * @param config The fixture configuration\n * @returns The fixture\n */\nexport function algorandFixture(fixtureConfig: AlgorandFixtureConfig | undefined, config: AlgoConfig): AlgorandFixture\n\nexport function algorandFixture(fixtureConfig?: AlgorandFixtureConfig, config?: AlgoConfig): AlgorandFixture {\n fixtureConfig = { ...fixtureConfig, ...config }\n if (!fixtureConfig.algod || !fixtureConfig.indexer || !fixtureConfig.kmd) {\n fixtureConfig = { ...ClientManager.getConfigFromEnvironmentOrLocalNet(), ...fixtureConfig }\n }\n\n const algod = fixtureConfig.algod ?? ClientManager.getAlgodClient(fixtureConfig.algodConfig!)\n const indexer = fixtureConfig.indexer ?? ClientManager.getIndexerClient(fixtureConfig.indexerConfig!)\n const kmd = fixtureConfig.kmd ?? ClientManager.getKmdClient(fixtureConfig.kmdConfig!)\n let context: AlgorandTestAutomationContext\n let algorand: AlgorandClient\n\n const newScope = async () => {\n Config.configure({ debug: true })\n const transactionLogger = new TransactionLogger()\n const transactionLoggerAlgod = transactionLogger.capture(algod)\n\n algorand = AlgorandClient.fromClients({ algod: transactionLoggerAlgod, indexer, kmd }).setSuggestedParamsCacheTimeout(0)\n\n const testAccount = await getTestAccount({ initialFunds: fixtureConfig?.testAccountFunding ?? algos(10), suppressLog: true }, algorand)\n algorand.setSignerFromAccount(testAccount)\n\n // If running against LocalNet we are likely in dev mode and we need to set a much higher validity window\n // otherwise we are more likely to get invalid transactions.\n if (await algorand.client.isLocalNet()) {\n algorand.setDefaultValidityWindow(1000)\n }\n context = {\n algorand,\n algod: transactionLoggerAlgod,\n indexer: indexer,\n kmd: kmd,\n testAccount,\n generateAccount: async (params: GetTestAccountParams) => {\n const account = await getTestAccount(params, algorand)\n algorand.setSignerFromAccount(account)\n return account\n },\n transactionLogger: transactionLogger,\n waitForIndexer: () => transactionLogger.waitForIndexer(indexer),\n waitForIndexerTransaction: (transactionId: string) => runWhenIndexerCaughtUp(() => indexer.lookupTransactionByID(transactionId).do()),\n }\n }\n\n return {\n get context() {\n if (!context) throw new Error('Context not initialised; make sure to call fixture.newScope() before accessing context.')\n return context\n },\n get algorand() {\n return algorand\n },\n beforeEach: newScope,\n newScope,\n }\n}\n"],"names":["config","ClientManager","indexer","Config","transactionLogger","TransactionLogger","AlgorandClient","getTestAccount","algos","account","runWhenIndexerCaughtUp"],"mappings":";;;;;;;;;;AA4EgB,SAAA,eAAe,CAAC,aAAqC,EAAEA,QAAmB,EAAA;IACxF,aAAa,GAAG,EAAE,GAAG,aAAa,EAAE,GAAGA,QAAM,EAAE;AAC/C,IAAA,IAAI,CAAC,aAAa,CAAC,KAAK,IAAI,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE;QACxE,aAAa,GAAG,EAAE,GAAGC,iCAAa,CAAC,kCAAkC,EAAE,EAAE,GAAG,aAAa,EAAE;;AAG7F,IAAA,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,IAAIA,iCAAa,CAAC,cAAc,CAAC,aAAa,CAAC,WAAY,CAAC;AAC7F,IAAA,MAAMC,SAAO,GAAG,aAAa,CAAC,OAAO,IAAID,iCAAa,CAAC,gBAAgB,CAAC,aAAa,CAAC,aAAc,CAAC;AACrG,IAAA,MAAM,GAAG,GAAG,aAAa,CAAC,GAAG,IAAIA,iCAAa,CAAC,YAAY,CAAC,aAAa,CAAC,SAAU,CAAC;AACrF,IAAA,IAAI,OAAsC;AAC1C,IAAA,IAAI,QAAwB;AAE5B,IAAA,MAAM,QAAQ,GAAG,YAAW;QAC1BE,aAAM,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACjC,QAAA,MAAMC,mBAAiB,GAAG,IAAIC,mCAAiB,EAAE;QACjD,MAAM,sBAAsB,GAAGD,mBAAiB,CAAC,OAAO,CAAC,KAAK,CAAC;QAE/D,QAAQ,GAAGE,mCAAc,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,sBAAsB,WAAEJ,SAAO,EAAE,GAAG,EAAE,CAAC,CAAC,8BAA8B,CAAC,CAAC,CAAC;QAExH,MAAM,WAAW,GAAG,MAAMK,sBAAc,CAAC,EAAE,YAAY,EAAE,aAAa,EAAE,kBAAkB,IAAIC,YAAK,CAAC,EAAE,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,QAAQ,CAAC;AACvI,QAAA,QAAQ,CAAC,oBAAoB,CAAC,WAAW,CAAC;;;QAI1C,IAAI,MAAM,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE;AACtC,YAAA,QAAQ,CAAC,wBAAwB,CAAC,IAAI,CAAC;;AAEzC,QAAA,OAAO,GAAG;YACR,QAAQ;AACR,YAAA,KAAK,EAAE,sBAAsB;AAC7B,YAAA,OAAO,EAAEN,SAAO;AAChB,YAAA,GAAG,EAAE,GAAG;YACR,WAAW;AACX,YAAA,eAAe,EAAE,OAAO,MAA4B,KAAI;gBACtD,MAAMO,SAAO,GAAG,MAAMF,sBAAc,CAAC,MAAM,EAAE,QAAQ,CAAC;AACtD,gBAAA,QAAQ,CAAC,oBAAoB,CAACE,SAAO,CAAC;AACtC,gBAAA,OAAOA,SAAO;aACf;AACD,YAAA,iBAAiB,EAAEL,mBAAiB;YACpC,cAAc,EAAE,MAAMA,mBAAiB,CAAC,cAAc,CAACF,SAAO,CAAC;YAC/D,yBAAyB,EAAE,CAAC,aAAqB,KAAKQ,8BAAsB,CAAC,MAAMR,SAAO,CAAC,qBAAqB,CAAC,aAAa,CAAC,CAAC,EAAE,EAAE,CAAC;SACtI;AACH,KAAC;IAED,OAAO;AACL,QAAA,IAAI,OAAO,GAAA;AACT,YAAA,IAAI,CAAC,OAAO;AAAE,gBAAA,MAAM,IAAI,KAAK,CAAC,yFAAyF,CAAC;AACxH,YAAA,OAAO,OAAO;SACf;AACD,QAAA,IAAI,QAAQ,GAAA;AACV,YAAA,OAAO,QAAQ;SAChB;AACD,QAAA,UAAU,EAAE,QAAQ;QACpB,QAAQ;KACT;AACH;;;;"}
1
+ {"version":3,"file":"algorand-fixture.js","sources":["../../../src/testing/fixtures/algorand-fixture.ts"],"sourcesContent":["import { algos, Config } from '../../'\nimport { AlgorandClient } from '../../types/algorand-client'\nimport { ClientManager } from '../../types/client-manager'\nimport { AlgoConfig } from '../../types/network-client'\nimport { AlgorandFixture, AlgorandFixtureConfig, AlgorandTestAutomationContext, GetTestAccountParams } from '../../types/testing'\nimport { getTestAccount } from '../account'\nimport { runWhenIndexerCaughtUp } from '../indexer'\nimport { TransactionLogger } from '../transaction-logger'\n\n/**\n * Creates a test fixture for automated testing against Algorand.\n * By default it tests against an environment variable specified client\n * if the standard environment variables are specified, otherwise against\n * a default LocalNet instance, but you can pass in an algod, indexer\n * and/or kmd (or their respective config) if you want to test against\n * an explicitly defined network.\n *\n * @example No config (per-test isolation)\n * ```typescript\n * const fixture = algorandFixture()\n *\n * beforeEach(fixture.newScope)\n *\n * test('My test', async () => {\n * const {algod, indexer, testAccount, ...} = fixture.context\n * // test things...\n * })\n * ```\n *\n * @example No config (test suite isolation)\n * ```typescript\n * const fixture = algorandFixture()\n *\n * beforeAll(fixture.newScope)\n *\n * test('My test', async () => {\n * const {algod, indexer, testAccount, ...} = fixture.context\n * // test things...\n * })\n * ```\n *\n * @example With config\n * ```typescript\n * const fixture = algorandFixture({\n * algod: new Algodv2('localhost', 12345, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),\n * // ...\n * })\n *\n * beforeEach(fixture.newScope)\n *\n * test('My test', async () => {\n * const {algod, indexer, testAccount, ...} = fixture.context\n * // test things...\n * })\n * ```\n *\n * @param fixtureConfig The fixture configuration\n * @returns The fixture\n */\nexport function algorandFixture(fixtureConfig?: AlgorandFixtureConfig): AlgorandFixture\n\n/**\n * @deprecated Config can be passed in directly to fixture config now.\n *\n * Creates a test fixture for automated testing against Algorand.\n * By default it tests against an environment variable specified client\n * if the standard environment variables are specified, otherwise against\n * a default LocalNet instance, but you can pass in an algod, indexer\n * and/or kmd if you want to test against an explicitly defined network.\n *\n * @param fixtureConfig The fixture configuration\n * @param config The fixture configuration\n * @returns The fixture\n */\nexport function algorandFixture(fixtureConfig: AlgorandFixtureConfig | undefined, config: AlgoConfig): AlgorandFixture\n\nexport function algorandFixture(fixtureConfig?: AlgorandFixtureConfig, config?: AlgoConfig): AlgorandFixture {\n fixtureConfig = { ...fixtureConfig, ...config }\n if (!fixtureConfig.algod || !fixtureConfig.indexer || !fixtureConfig.kmd) {\n fixtureConfig = { ...ClientManager.getConfigFromEnvironmentOrLocalNet(), ...fixtureConfig }\n }\n\n const algod = fixtureConfig.algod ?? ClientManager.getAlgodClient(fixtureConfig.algodConfig!)\n const indexer = fixtureConfig.indexer ?? ClientManager.getIndexerClient(fixtureConfig.indexerConfig!)\n const kmd = fixtureConfig.kmd ?? ClientManager.getKmdClient(fixtureConfig.kmdConfig!)\n let context: AlgorandTestAutomationContext\n let algorand: AlgorandClient\n\n const newScope = async () => {\n Config.configure({ debug: true })\n const transactionLogger = new TransactionLogger()\n const transactionLoggerAlgod = transactionLogger.capture(algod)\n\n algorand = AlgorandClient.fromClients({ algod: transactionLoggerAlgod, indexer, kmd }).setSuggestedParamsCacheTimeout(0)\n\n const testAccount = await getTestAccount({ initialFunds: fixtureConfig?.testAccountFunding ?? algos(10), suppressLog: true }, algorand)\n algorand.setSignerFromAccount(testAccount)\n\n // If running against LocalNet we are likely in dev mode and we need to set a much higher validity window\n // otherwise we are more likely to get invalid transactions.\n if (await algorand.client.isLocalNet()) {\n algorand.setDefaultValidityWindow(1000)\n }\n context = {\n algorand,\n algod: transactionLoggerAlgod,\n indexer: indexer,\n kmd: kmd,\n testAccount,\n generateAccount: async (params: GetTestAccountParams) => {\n const account = await getTestAccount(params, algorand)\n algorand.setSignerFromAccount(account)\n return account\n },\n transactionLogger: transactionLogger,\n waitForIndexer: () => transactionLogger.waitForIndexer(indexer),\n waitForIndexerTransaction: (transactionId: string) => runWhenIndexerCaughtUp(() => indexer.lookupTransactionByID(transactionId).do()),\n }\n }\n\n return {\n get context() {\n if (!context) throw new Error('Context not initialised; make sure to call fixture.newScope() before accessing context.')\n return context\n },\n get algorand() {\n return algorand\n },\n beforeEach: newScope,\n newScope,\n }\n}\n"],"names":["config","ClientManager","indexer","Config","transactionLogger","TransactionLogger","AlgorandClient","getTestAccount","algos","account","runWhenIndexerCaughtUp"],"mappings":";;;;;;;;;;AA4EgB,SAAA,eAAe,CAAC,aAAqC,EAAEA,QAAmB,EAAA;IACxF,aAAa,GAAG,EAAE,GAAG,aAAa,EAAE,GAAGA,QAAM,EAAE;AAC/C,IAAA,IAAI,CAAC,aAAa,CAAC,KAAK,IAAI,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE;QACxE,aAAa,GAAG,EAAE,GAAGC,iCAAa,CAAC,kCAAkC,EAAE,EAAE,GAAG,aAAa,EAAE;;AAG7F,IAAA,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,IAAIA,iCAAa,CAAC,cAAc,CAAC,aAAa,CAAC,WAAY,CAAC;AAC7F,IAAA,MAAMC,SAAO,GAAG,aAAa,CAAC,OAAO,IAAID,iCAAa,CAAC,gBAAgB,CAAC,aAAa,CAAC,aAAc,CAAC;AACrG,IAAA,MAAM,GAAG,GAAG,aAAa,CAAC,GAAG,IAAIA,iCAAa,CAAC,YAAY,CAAC,aAAa,CAAC,SAAU,CAAC;AACrF,IAAA,IAAI,OAAsC;AAC1C,IAAA,IAAI,QAAwB;AAE5B,IAAA,MAAM,QAAQ,GAAG,YAAW;QAC1BE,aAAM,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACjC,QAAA,MAAMC,mBAAiB,GAAG,IAAIC,mCAAiB,EAAE;QACjD,MAAM,sBAAsB,GAAGD,mBAAiB,CAAC,OAAO,CAAC,KAAK,CAAC;QAE/D,QAAQ,GAAGE,mCAAc,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,sBAAsB,WAAEJ,SAAO,EAAE,GAAG,EAAE,CAAC,CAAC,8BAA8B,CAAC,CAAC,CAAC;QAExH,MAAM,WAAW,GAAG,MAAMK,sBAAc,CAAC,EAAE,YAAY,EAAE,aAAa,EAAE,kBAAkB,IAAIC,YAAK,CAAC,EAAE,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,QAAQ,CAAC;AACvI,QAAA,QAAQ,CAAC,oBAAoB,CAAC,WAAW,CAAC;;;QAI1C,IAAI,MAAM,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE;AACtC,YAAA,QAAQ,CAAC,wBAAwB,CAAC,IAAI,CAAC;;AAEzC,QAAA,OAAO,GAAG;YACR,QAAQ;AACR,YAAA,KAAK,EAAE,sBAAsB;AAC7B,YAAA,OAAO,EAAEN,SAAO;AAChB,YAAA,GAAG,EAAE,GAAG;YACR,WAAW;AACX,YAAA,eAAe,EAAE,OAAO,MAA4B,KAAI;gBACtD,MAAMO,SAAO,GAAG,MAAMF,sBAAc,CAAC,MAAM,EAAE,QAAQ,CAAC;AACtD,gBAAA,QAAQ,CAAC,oBAAoB,CAACE,SAAO,CAAC;AACtC,gBAAA,OAAOA,SAAO;aACf;AACD,YAAA,iBAAiB,EAAEL,mBAAiB;YACpC,cAAc,EAAE,MAAMA,mBAAiB,CAAC,cAAc,CAACF,SAAO,CAAC;YAC/D,yBAAyB,EAAE,CAAC,aAAqB,KAAKQ,8BAAsB,CAAC,MAAMR,SAAO,CAAC,qBAAqB,CAAC,aAAa,CAAC,CAAC,EAAE,EAAE,CAAC;SACtI;AACH,KAAC;IAED,OAAO;AACL,QAAA,IAAI,OAAO,GAAA;AACT,YAAA,IAAI,CAAC,OAAO;AAAE,gBAAA,MAAM,IAAI,KAAK,CAAC,yFAAyF,CAAC;AACxH,YAAA,OAAO,OAAO;SACf;AACD,QAAA,IAAI,QAAQ,GAAA;AACV,YAAA,OAAO,QAAQ;SAChB;AACD,QAAA,UAAU,EAAE,QAAQ;QACpB,QAAQ;KACT;AACH;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"algorand-fixture.mjs","sources":["../../../src/testing/fixtures/algorand-fixture.ts"],"sourcesContent":["import { algos, Config } from '../../'\nimport { AlgorandClient } from '../../types/algorand-client'\nimport { ClientManager } from '../../types/client-manager'\nimport { AlgoConfig } from '../../types/network-client'\nimport { AlgorandFixture, AlgorandFixtureConfig, AlgorandTestAutomationContext, GetTestAccountParams } from '../../types/testing'\nimport { getTestAccount } from '../account'\nimport { runWhenIndexerCaughtUp } from '../indexer'\nimport { TransactionLogger } from '../transaction-logger'\n\n/**\n * Creates a test fixture for automated testing against Algorand.\n * By default it tests against an environment variable specified client\n * if the standard environment variables are specified, otherwise against\n * a default LocalNet instance, but you can pass in an algod, indexer\n * and/or kmd (or their respective config) if you want to test against\n * an explicitly defined network.\n *\n * @example No config (per-test isolation)\n * ```typescript\n * const fixture = algorandFixture()\n *\n * beforeEach(fixture.newScope, 10_000)\n *\n * test('My test', async () => {\n * const {algod, indexer, testAccount, ...} = fixture.context\n * // test things...\n * })\n * ```\n *\n * @example No config (test suite isolation)\n * ```typescript\n * const fixture = algorandFixture()\n *\n * beforeAll(fixture.newScope, 10_000)\n *\n * test('My test', async () => {\n * const {algod, indexer, testAccount, ...} = fixture.context\n * // test things...\n * })\n * ```\n *\n * @example With config\n * ```typescript\n * const fixture = algorandFixture({\n * algod: new Algodv2('localhost', 12345, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),\n * // ...\n * })\n *\n * beforeEach(fixture.newScope, 10_000)\n *\n * test('My test', async () => {\n * const {algod, indexer, testAccount, ...} = fixture.context\n * // test things...\n * })\n * ```\n *\n * @param fixtureConfig The fixture configuration\n * @returns The fixture\n */\nexport function algorandFixture(fixtureConfig?: AlgorandFixtureConfig): AlgorandFixture\n\n/**\n * @deprecated Config can be passed in directly to fixture config now.\n *\n * Creates a test fixture for automated testing against Algorand.\n * By default it tests against an environment variable specified client\n * if the standard environment variables are specified, otherwise against\n * a default LocalNet instance, but you can pass in an algod, indexer\n * and/or kmd if you want to test against an explicitly defined network.\n *\n * @param fixtureConfig The fixture configuration\n * @param config The fixture configuration\n * @returns The fixture\n */\nexport function algorandFixture(fixtureConfig: AlgorandFixtureConfig | undefined, config: AlgoConfig): AlgorandFixture\n\nexport function algorandFixture(fixtureConfig?: AlgorandFixtureConfig, config?: AlgoConfig): AlgorandFixture {\n fixtureConfig = { ...fixtureConfig, ...config }\n if (!fixtureConfig.algod || !fixtureConfig.indexer || !fixtureConfig.kmd) {\n fixtureConfig = { ...ClientManager.getConfigFromEnvironmentOrLocalNet(), ...fixtureConfig }\n }\n\n const algod = fixtureConfig.algod ?? ClientManager.getAlgodClient(fixtureConfig.algodConfig!)\n const indexer = fixtureConfig.indexer ?? ClientManager.getIndexerClient(fixtureConfig.indexerConfig!)\n const kmd = fixtureConfig.kmd ?? ClientManager.getKmdClient(fixtureConfig.kmdConfig!)\n let context: AlgorandTestAutomationContext\n let algorand: AlgorandClient\n\n const newScope = async () => {\n Config.configure({ debug: true })\n const transactionLogger = new TransactionLogger()\n const transactionLoggerAlgod = transactionLogger.capture(algod)\n\n algorand = AlgorandClient.fromClients({ algod: transactionLoggerAlgod, indexer, kmd }).setSuggestedParamsCacheTimeout(0)\n\n const testAccount = await getTestAccount({ initialFunds: fixtureConfig?.testAccountFunding ?? algos(10), suppressLog: true }, algorand)\n algorand.setSignerFromAccount(testAccount)\n\n // If running against LocalNet we are likely in dev mode and we need to set a much higher validity window\n // otherwise we are more likely to get invalid transactions.\n if (await algorand.client.isLocalNet()) {\n algorand.setDefaultValidityWindow(1000)\n }\n context = {\n algorand,\n algod: transactionLoggerAlgod,\n indexer: indexer,\n kmd: kmd,\n testAccount,\n generateAccount: async (params: GetTestAccountParams) => {\n const account = await getTestAccount(params, algorand)\n algorand.setSignerFromAccount(account)\n return account\n },\n transactionLogger: transactionLogger,\n waitForIndexer: () => transactionLogger.waitForIndexer(indexer),\n waitForIndexerTransaction: (transactionId: string) => runWhenIndexerCaughtUp(() => indexer.lookupTransactionByID(transactionId).do()),\n }\n }\n\n return {\n get context() {\n if (!context) throw new Error('Context not initialised; make sure to call fixture.newScope() before accessing context.')\n return context\n },\n get algorand() {\n return algorand\n },\n beforeEach: newScope,\n newScope,\n }\n}\n"],"names":[],"mappings":";;;;;;;;AA4EgB,SAAA,eAAe,CAAC,aAAqC,EAAE,MAAmB,EAAA;IACxF,aAAa,GAAG,EAAE,GAAG,aAAa,EAAE,GAAG,MAAM,EAAE;AAC/C,IAAA,IAAI,CAAC,aAAa,CAAC,KAAK,IAAI,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE;QACxE,aAAa,GAAG,EAAE,GAAG,aAAa,CAAC,kCAAkC,EAAE,EAAE,GAAG,aAAa,EAAE;;AAG7F,IAAA,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,IAAI,aAAa,CAAC,cAAc,CAAC,aAAa,CAAC,WAAY,CAAC;AAC7F,IAAA,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,IAAI,aAAa,CAAC,gBAAgB,CAAC,aAAa,CAAC,aAAc,CAAC;AACrG,IAAA,MAAM,GAAG,GAAG,aAAa,CAAC,GAAG,IAAI,aAAa,CAAC,YAAY,CAAC,aAAa,CAAC,SAAU,CAAC;AACrF,IAAA,IAAI,OAAsC;AAC1C,IAAA,IAAI,QAAwB;AAE5B,IAAA,MAAM,QAAQ,GAAG,YAAW;QAC1B,MAAM,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACjC,QAAA,MAAM,iBAAiB,GAAG,IAAI,iBAAiB,EAAE;QACjD,MAAM,sBAAsB,GAAG,iBAAiB,CAAC,OAAO,CAAC,KAAK,CAAC;QAE/D,QAAQ,GAAG,cAAc,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,sBAAsB,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,8BAA8B,CAAC,CAAC,CAAC;QAExH,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,EAAE,YAAY,EAAE,aAAa,EAAE,kBAAkB,IAAI,KAAK,CAAC,EAAE,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,QAAQ,CAAC;AACvI,QAAA,QAAQ,CAAC,oBAAoB,CAAC,WAAW,CAAC;;;QAI1C,IAAI,MAAM,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE;AACtC,YAAA,QAAQ,CAAC,wBAAwB,CAAC,IAAI,CAAC;;AAEzC,QAAA,OAAO,GAAG;YACR,QAAQ;AACR,YAAA,KAAK,EAAE,sBAAsB;AAC7B,YAAA,OAAO,EAAE,OAAO;AAChB,YAAA,GAAG,EAAE,GAAG;YACR,WAAW;AACX,YAAA,eAAe,EAAE,OAAO,MAA4B,KAAI;gBACtD,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC;AACtD,gBAAA,QAAQ,CAAC,oBAAoB,CAAC,OAAO,CAAC;AACtC,gBAAA,OAAO,OAAO;aACf;AACD,YAAA,iBAAiB,EAAE,iBAAiB;YACpC,cAAc,EAAE,MAAM,iBAAiB,CAAC,cAAc,CAAC,OAAO,CAAC;YAC/D,yBAAyB,EAAE,CAAC,aAAqB,KAAK,sBAAsB,CAAC,MAAM,OAAO,CAAC,qBAAqB,CAAC,aAAa,CAAC,CAAC,EAAE,EAAE,CAAC;SACtI;AACH,KAAC;IAED,OAAO;AACL,QAAA,IAAI,OAAO,GAAA;AACT,YAAA,IAAI,CAAC,OAAO;AAAE,gBAAA,MAAM,IAAI,KAAK,CAAC,yFAAyF,CAAC;AACxH,YAAA,OAAO,OAAO;SACf;AACD,QAAA,IAAI,QAAQ,GAAA;AACV,YAAA,OAAO,QAAQ;SAChB;AACD,QAAA,UAAU,EAAE,QAAQ;QACpB,QAAQ;KACT;AACH;;;;"}
1
+ {"version":3,"file":"algorand-fixture.mjs","sources":["../../../src/testing/fixtures/algorand-fixture.ts"],"sourcesContent":["import { algos, Config } from '../../'\nimport { AlgorandClient } from '../../types/algorand-client'\nimport { ClientManager } from '../../types/client-manager'\nimport { AlgoConfig } from '../../types/network-client'\nimport { AlgorandFixture, AlgorandFixtureConfig, AlgorandTestAutomationContext, GetTestAccountParams } from '../../types/testing'\nimport { getTestAccount } from '../account'\nimport { runWhenIndexerCaughtUp } from '../indexer'\nimport { TransactionLogger } from '../transaction-logger'\n\n/**\n * Creates a test fixture for automated testing against Algorand.\n * By default it tests against an environment variable specified client\n * if the standard environment variables are specified, otherwise against\n * a default LocalNet instance, but you can pass in an algod, indexer\n * and/or kmd (or their respective config) if you want to test against\n * an explicitly defined network.\n *\n * @example No config (per-test isolation)\n * ```typescript\n * const fixture = algorandFixture()\n *\n * beforeEach(fixture.newScope)\n *\n * test('My test', async () => {\n * const {algod, indexer, testAccount, ...} = fixture.context\n * // test things...\n * })\n * ```\n *\n * @example No config (test suite isolation)\n * ```typescript\n * const fixture = algorandFixture()\n *\n * beforeAll(fixture.newScope)\n *\n * test('My test', async () => {\n * const {algod, indexer, testAccount, ...} = fixture.context\n * // test things...\n * })\n * ```\n *\n * @example With config\n * ```typescript\n * const fixture = algorandFixture({\n * algod: new Algodv2('localhost', 12345, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),\n * // ...\n * })\n *\n * beforeEach(fixture.newScope)\n *\n * test('My test', async () => {\n * const {algod, indexer, testAccount, ...} = fixture.context\n * // test things...\n * })\n * ```\n *\n * @param fixtureConfig The fixture configuration\n * @returns The fixture\n */\nexport function algorandFixture(fixtureConfig?: AlgorandFixtureConfig): AlgorandFixture\n\n/**\n * @deprecated Config can be passed in directly to fixture config now.\n *\n * Creates a test fixture for automated testing against Algorand.\n * By default it tests against an environment variable specified client\n * if the standard environment variables are specified, otherwise against\n * a default LocalNet instance, but you can pass in an algod, indexer\n * and/or kmd if you want to test against an explicitly defined network.\n *\n * @param fixtureConfig The fixture configuration\n * @param config The fixture configuration\n * @returns The fixture\n */\nexport function algorandFixture(fixtureConfig: AlgorandFixtureConfig | undefined, config: AlgoConfig): AlgorandFixture\n\nexport function algorandFixture(fixtureConfig?: AlgorandFixtureConfig, config?: AlgoConfig): AlgorandFixture {\n fixtureConfig = { ...fixtureConfig, ...config }\n if (!fixtureConfig.algod || !fixtureConfig.indexer || !fixtureConfig.kmd) {\n fixtureConfig = { ...ClientManager.getConfigFromEnvironmentOrLocalNet(), ...fixtureConfig }\n }\n\n const algod = fixtureConfig.algod ?? ClientManager.getAlgodClient(fixtureConfig.algodConfig!)\n const indexer = fixtureConfig.indexer ?? ClientManager.getIndexerClient(fixtureConfig.indexerConfig!)\n const kmd = fixtureConfig.kmd ?? ClientManager.getKmdClient(fixtureConfig.kmdConfig!)\n let context: AlgorandTestAutomationContext\n let algorand: AlgorandClient\n\n const newScope = async () => {\n Config.configure({ debug: true })\n const transactionLogger = new TransactionLogger()\n const transactionLoggerAlgod = transactionLogger.capture(algod)\n\n algorand = AlgorandClient.fromClients({ algod: transactionLoggerAlgod, indexer, kmd }).setSuggestedParamsCacheTimeout(0)\n\n const testAccount = await getTestAccount({ initialFunds: fixtureConfig?.testAccountFunding ?? algos(10), suppressLog: true }, algorand)\n algorand.setSignerFromAccount(testAccount)\n\n // If running against LocalNet we are likely in dev mode and we need to set a much higher validity window\n // otherwise we are more likely to get invalid transactions.\n if (await algorand.client.isLocalNet()) {\n algorand.setDefaultValidityWindow(1000)\n }\n context = {\n algorand,\n algod: transactionLoggerAlgod,\n indexer: indexer,\n kmd: kmd,\n testAccount,\n generateAccount: async (params: GetTestAccountParams) => {\n const account = await getTestAccount(params, algorand)\n algorand.setSignerFromAccount(account)\n return account\n },\n transactionLogger: transactionLogger,\n waitForIndexer: () => transactionLogger.waitForIndexer(indexer),\n waitForIndexerTransaction: (transactionId: string) => runWhenIndexerCaughtUp(() => indexer.lookupTransactionByID(transactionId).do()),\n }\n }\n\n return {\n get context() {\n if (!context) throw new Error('Context not initialised; make sure to call fixture.newScope() before accessing context.')\n return context\n },\n get algorand() {\n return algorand\n },\n beforeEach: newScope,\n newScope,\n }\n}\n"],"names":[],"mappings":";;;;;;;;AA4EgB,SAAA,eAAe,CAAC,aAAqC,EAAE,MAAmB,EAAA;IACxF,aAAa,GAAG,EAAE,GAAG,aAAa,EAAE,GAAG,MAAM,EAAE;AAC/C,IAAA,IAAI,CAAC,aAAa,CAAC,KAAK,IAAI,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE;QACxE,aAAa,GAAG,EAAE,GAAG,aAAa,CAAC,kCAAkC,EAAE,EAAE,GAAG,aAAa,EAAE;;AAG7F,IAAA,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,IAAI,aAAa,CAAC,cAAc,CAAC,aAAa,CAAC,WAAY,CAAC;AAC7F,IAAA,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,IAAI,aAAa,CAAC,gBAAgB,CAAC,aAAa,CAAC,aAAc,CAAC;AACrG,IAAA,MAAM,GAAG,GAAG,aAAa,CAAC,GAAG,IAAI,aAAa,CAAC,YAAY,CAAC,aAAa,CAAC,SAAU,CAAC;AACrF,IAAA,IAAI,OAAsC;AAC1C,IAAA,IAAI,QAAwB;AAE5B,IAAA,MAAM,QAAQ,GAAG,YAAW;QAC1B,MAAM,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACjC,QAAA,MAAM,iBAAiB,GAAG,IAAI,iBAAiB,EAAE;QACjD,MAAM,sBAAsB,GAAG,iBAAiB,CAAC,OAAO,CAAC,KAAK,CAAC;QAE/D,QAAQ,GAAG,cAAc,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,sBAAsB,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,8BAA8B,CAAC,CAAC,CAAC;QAExH,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,EAAE,YAAY,EAAE,aAAa,EAAE,kBAAkB,IAAI,KAAK,CAAC,EAAE,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,QAAQ,CAAC;AACvI,QAAA,QAAQ,CAAC,oBAAoB,CAAC,WAAW,CAAC;;;QAI1C,IAAI,MAAM,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE;AACtC,YAAA,QAAQ,CAAC,wBAAwB,CAAC,IAAI,CAAC;;AAEzC,QAAA,OAAO,GAAG;YACR,QAAQ;AACR,YAAA,KAAK,EAAE,sBAAsB;AAC7B,YAAA,OAAO,EAAE,OAAO;AAChB,YAAA,GAAG,EAAE,GAAG;YACR,WAAW;AACX,YAAA,eAAe,EAAE,OAAO,MAA4B,KAAI;gBACtD,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC;AACtD,gBAAA,QAAQ,CAAC,oBAAoB,CAAC,OAAO,CAAC;AACtC,gBAAA,OAAO,OAAO;aACf;AACD,YAAA,iBAAiB,EAAE,iBAAiB;YACpC,cAAc,EAAE,MAAM,iBAAiB,CAAC,cAAc,CAAC,OAAO,CAAC;YAC/D,yBAAyB,EAAE,CAAC,aAAqB,KAAK,sBAAsB,CAAC,MAAM,OAAO,CAAC,qBAAqB,CAAC,aAAa,CAAC,CAAC,EAAE,EAAE,CAAC;SACtI;AACH,KAAC;IAED,OAAO;AACL,QAAA,IAAI,OAAO,GAAA;AACT,YAAA,IAAI,CAAC,OAAO;AAAE,gBAAA,MAAM,IAAI,KAAK,CAAC,yFAAyF,CAAC;AACxH,YAAA,OAAO,OAAO;SACf;AACD,QAAA,IAAI,QAAQ,GAAA;AACV,YAAA,OAAO,QAAQ;SAChB;AACD,QAAA,UAAU,EAAE,QAAQ;QACpB,QAAQ;KACT;AACH;;;;"}
@@ -28,7 +28,7 @@ export declare function _getAppArgsForABICall(args: ABIAppCallArgs, from: SendTr
28
28
  appForeignApps: number[] | undefined;
29
29
  appForeignAssets: number[] | undefined;
30
30
  appAccounts: string[] | undefined;
31
- methodArgs: (string | number | bigint | boolean | Uint8Array | algosdk.ABIValue[] | algosdk.TransactionWithSigner)[];
31
+ methodArgs: (string | number | bigint | boolean | algosdk.Address | Uint8Array | algosdk.ABIValue[] | algosdk.TransactionWithSigner)[];
32
32
  rekeyTo: string | undefined;
33
33
  }>;
34
34
  /** @deprecated */
@@ -10,7 +10,7 @@ import Transaction = algosdk.Transaction;
10
10
  import TransactionWithSigner = algosdk.TransactionWithSigner;
11
11
  export declare const MAX_TRANSACTION_GROUP_SIZE = 16;
12
12
  export declare const MAX_APP_CALL_FOREIGN_REFERENCES = 8;
13
- export declare const MAX_APP_CALL_ACCOUNT_REFERENCES = 4;
13
+ export declare const MAX_APP_CALL_ACCOUNT_REFERENCES = 8;
14
14
  /**
15
15
  * @deprecated Convert your data to a `string` or `Uint8Array`, if using ARC-2 use `TransactionComposer.arc2Note`.
16
16
  *
@@ -10,7 +10,7 @@ var performAtomicTransactionComposerSimulate = require('./perform-atomic-transac
10
10
  var AtomicTransactionComposer = algosdk.AtomicTransactionComposer;
11
11
  const MAX_TRANSACTION_GROUP_SIZE = 16;
12
12
  const MAX_APP_CALL_FOREIGN_REFERENCES = 8;
13
- const MAX_APP_CALL_ACCOUNT_REFERENCES = 4;
13
+ const MAX_APP_CALL_ACCOUNT_REFERENCES = 8;
14
14
  /**
15
15
  * @deprecated Convert your data to a `string` or `Uint8Array`, if using ARC-2 use `TransactionComposer.arc2Note`.
16
16
  *
@@ -259,8 +259,31 @@ async function getGroupExecutionInfo(atc, algod, sendParams, additionalAtcContex
259
259
  }
260
260
  throw Error(`Error resolving execution info via simulate in transaction ${groupResponse.failedAt}: ${groupResponse.failureMessage}`);
261
261
  }
262
+ const sortedResources = groupResponse.unnamedResourcesAccessed;
263
+ // NOTE: We explicitly want to avoid localeCompare as that can lead to different results in different environments
264
+ const compare = (a, b) => (a < b ? -1 : a > b ? 1 : 0);
265
+ if (sortedResources) {
266
+ sortedResources.accounts?.sort((a, b) => compare(a.toString(), b.toString()));
267
+ sortedResources.assets?.sort(compare);
268
+ sortedResources.apps?.sort(compare);
269
+ sortedResources.boxes?.sort((a, b) => {
270
+ const aStr = `${a.app}-${a.name}`;
271
+ const bStr = `${b.app}-${b.name}`;
272
+ return compare(aStr, bStr);
273
+ });
274
+ sortedResources.appLocals?.sort((a, b) => {
275
+ const aStr = `${a.app}-${a.account}`;
276
+ const bStr = `${b.app}-${b.account}`;
277
+ return compare(aStr, bStr);
278
+ });
279
+ sortedResources.assetHoldings?.sort((a, b) => {
280
+ const aStr = `${a.asset}-${a.account}`;
281
+ const bStr = `${b.asset}-${b.account}`;
282
+ return compare(aStr, bStr);
283
+ });
284
+ }
262
285
  return {
263
- groupUnnamedResourcesAccessed: sendParams.populateAppCallResources ? groupResponse.unnamedResourcesAccessed : undefined,
286
+ groupUnnamedResourcesAccessed: sendParams.populateAppCallResources ? sortedResources : undefined,
264
287
  txns: groupResponse.txnResults.map((txn, i) => {
265
288
  const originalTxn = atc['transactions'][i].txn;
266
289
  let requiredFeeDelta = 0n;
@@ -379,30 +402,40 @@ async function prepareGroupForSending(atc, algod, sendParams, additionalAtcConte
379
402
  new Map(),
380
403
  ])
381
404
  : [0n, new Map()];
405
+ const appCallHasAccessReferences = (txn) => {
406
+ return txn.type === algosdk.TransactionType.appl && txn.applicationCall?.access && txn.applicationCall?.access.length > 0;
407
+ };
408
+ const indexesWithAccessReferences = [];
382
409
  executionInfo.txns.forEach(({ unnamedResourcesAccessed: r }, i) => {
383
410
  // Populate Transaction App Call Resources
384
- if (sendParams.populateAppCallResources && r !== undefined && group[i].txn.type === algosdk.TransactionType.appl) {
385
- if (r.boxes || r.extraBoxRefs)
386
- throw Error('Unexpected boxes at the transaction level');
387
- if (r.appLocals)
388
- throw Error('Unexpected app local at the transaction level');
389
- if (r.assetHoldings)
390
- throw Error('Unexpected asset holding at the transaction level');
391
- group[i].txn['applicationCall'] = {
392
- ...group[i].txn.applicationCall,
393
- accounts: [...(group[i].txn?.applicationCall?.accounts ?? []), ...(r.accounts ?? [])],
394
- foreignApps: [...(group[i].txn?.applicationCall?.foreignApps ?? []), ...(r.apps ?? [])],
395
- foreignAssets: [...(group[i].txn?.applicationCall?.foreignAssets ?? []), ...(r.assets ?? [])],
396
- boxes: [...(group[i].txn?.applicationCall?.boxes ?? []), ...(r.boxes ?? [])],
397
- };
398
- const accounts = group[i].txn.applicationCall?.accounts?.length ?? 0;
399
- if (accounts > MAX_APP_CALL_ACCOUNT_REFERENCES)
400
- throw Error(`Account reference limit of ${MAX_APP_CALL_ACCOUNT_REFERENCES} exceeded in transaction ${i}`);
401
- const assets = group[i].txn.applicationCall?.foreignAssets?.length ?? 0;
402
- const apps = group[i].txn.applicationCall?.foreignApps?.length ?? 0;
403
- const boxes = group[i].txn.applicationCall?.boxes?.length ?? 0;
404
- if (accounts + assets + apps + boxes > MAX_APP_CALL_FOREIGN_REFERENCES) {
405
- throw Error(`Resource reference limit of ${MAX_APP_CALL_FOREIGN_REFERENCES} exceeded in transaction ${i}`);
411
+ if (sendParams.populateAppCallResources && group[i].txn.type === algosdk.TransactionType.appl) {
412
+ const hasAccessReferences = appCallHasAccessReferences(group[i].txn);
413
+ if (hasAccessReferences && (r || executionInfo.groupUnnamedResourcesAccessed)) {
414
+ indexesWithAccessReferences.push(i);
415
+ }
416
+ if (r && !hasAccessReferences) {
417
+ if (r.boxes || r.extraBoxRefs)
418
+ throw Error('Unexpected boxes at the transaction level');
419
+ if (r.appLocals)
420
+ throw Error('Unexpected app local at the transaction level');
421
+ if (r.assetHoldings)
422
+ throw Error('Unexpected asset holding at the transaction level');
423
+ group[i].txn['applicationCall'] = {
424
+ ...group[i].txn.applicationCall,
425
+ accounts: [...(group[i].txn?.applicationCall?.accounts ?? []), ...(r.accounts ?? [])],
426
+ foreignApps: [...(group[i].txn?.applicationCall?.foreignApps ?? []), ...(r.apps ?? [])],
427
+ foreignAssets: [...(group[i].txn?.applicationCall?.foreignAssets ?? []), ...(r.assets ?? [])],
428
+ boxes: [...(group[i].txn?.applicationCall?.boxes ?? []), ...(r.boxes ?? [])],
429
+ };
430
+ const accounts = group[i].txn.applicationCall?.accounts?.length ?? 0;
431
+ if (accounts > MAX_APP_CALL_ACCOUNT_REFERENCES)
432
+ throw Error(`Account reference limit of ${MAX_APP_CALL_ACCOUNT_REFERENCES} exceeded in transaction ${i}`);
433
+ const assets = group[i].txn.applicationCall?.foreignAssets?.length ?? 0;
434
+ const apps = group[i].txn.applicationCall?.foreignApps?.length ?? 0;
435
+ const boxes = group[i].txn.applicationCall?.boxes?.length ?? 0;
436
+ if (accounts + assets + apps + boxes > MAX_APP_CALL_FOREIGN_REFERENCES) {
437
+ throw Error(`Resource reference limit of ${MAX_APP_CALL_FOREIGN_REFERENCES} exceeded in transaction ${i}`);
438
+ }
406
439
  }
407
440
  }
408
441
  // Cover App Call Inner Transaction Fees
@@ -423,10 +456,15 @@ async function prepareGroupForSending(atc, algod, sendParams, additionalAtcConte
423
456
  });
424
457
  // Populate Group App Call Resources
425
458
  if (sendParams.populateAppCallResources) {
459
+ if (indexesWithAccessReferences.length > 0) {
460
+ config.Config.logger.warn(`Resource population will be skipped for transaction indexes ${indexesWithAccessReferences.join(', ')} as they use access references.`);
461
+ }
426
462
  const populateGroupResource = (txns, reference, type) => {
427
463
  const isApplBelowLimit = (t) => {
428
464
  if (t.txn.type !== algosdk.TransactionType.appl)
429
465
  return false;
466
+ if (appCallHasAccessReferences(t.txn))
467
+ return false;
430
468
  const accounts = t.txn.applicationCall?.accounts?.length ?? 0;
431
469
  const assets = t.txn.applicationCall?.foreignAssets?.length ?? 0;
432
470
  const apps = t.txn.applicationCall?.foreignApps?.length ?? 0;
@@ -510,12 +548,14 @@ async function prepareGroupForSending(atc, algod, sendParams, additionalAtcConte
510
548
  const txnIndex = txns.findIndex((t) => {
511
549
  if (t.txn.type !== algosdk.TransactionType.appl)
512
550
  return false;
551
+ if (appCallHasAccessReferences(t.txn))
552
+ return false;
513
553
  const accounts = t.txn.applicationCall?.accounts?.length ?? 0;
514
- if (type === 'account')
515
- return accounts < MAX_APP_CALL_ACCOUNT_REFERENCES;
516
554
  const assets = t.txn.applicationCall?.foreignAssets?.length ?? 0;
517
555
  const apps = t.txn.applicationCall?.foreignApps?.length ?? 0;
518
556
  const boxes = t.txn.applicationCall?.boxes?.length ?? 0;
557
+ if (type === 'account')
558
+ return accounts < MAX_APP_CALL_ACCOUNT_REFERENCES && accounts + assets + apps + boxes < MAX_APP_CALL_FOREIGN_REFERENCES;
519
559
  // If we're adding local state or asset holding, we need space for the acocunt and the other reference
520
560
  if (type === 'assetHolding' || type === 'appLocal') {
521
561
  return accounts + assets + apps + boxes < MAX_APP_CALL_FOREIGN_REFERENCES - 1 && accounts < MAX_APP_CALL_ACCOUNT_REFERENCES;