diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 0395510..0000000 --- a/.eslintignore +++ /dev/null @@ -1,15 +0,0 @@ -# don't lint the linter config -.eslintrc.js -# don't ever lint node_modules -node_modules -# don't lint build output (make sure it's set to your correct build folder name) -dist -build -# don't lint nyc coverage output -coverage -# don't lint generated types -**/generated/types.d.ts -**/generated/types.ts -# don't lint ide files -.idea -.vscode diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 1c69481..0000000 --- a/.eslintrc +++ /dev/null @@ -1,27 +0,0 @@ -{ - "root": true, - "env": { - "node": true - }, - "extends": ["@makerx/eslint-config"], - "rules": { - "no-restricted-syntax": [ - "error", - { - // Algosdk v2.x.x exports a malformed ES module and when using subscriber-ts in an ESM project - // the CJS module may be loaded, which may not fuly support all named exports. - // The easiest solution for now, is to only use the default export. - "message": "Only use the default export in 'algosdk'. See rule comment for details", - "selector": "ImportDeclaration[source.value=\"algosdk\"] ImportSpecifier" - } - ] - }, - "overrides": [ - { - "files": ["tests/**/*.ts"], - "rules": { - "no-restricted-syntax": 0 - } - } - ] -} diff --git a/docs/code/modules/index.md b/docs/code/modules/index.md index 02cc148..8dfbee1 100644 --- a/docs/code/modules/index.md +++ b/docs/code/modules/index.md @@ -37,4 +37,4 @@ The result of this subscription pull/poll. #### Defined in -[subscriptions.ts:58](https://github.com/algorandfoundation/algokit-subscriber-ts/blob/main/src/subscriptions.ts#L58) +[subscriptions.ts:57](https://github.com/algorandfoundation/algokit-subscriber-ts/blob/main/src/subscriptions.ts#L57) diff --git a/docs/subscriptions.md b/docs/subscriptions.md index f2baf93..d78e75f 100644 --- a/docs/subscriptions.md +++ b/docs/subscriptions.md @@ -340,7 +340,8 @@ If you ran the following code on a cron schedule of (say) every 5 seconds it wou it would drop old records and restart notifications from the new tip. ```typescript -const algod = await algokit.getAlgoClient() +const algorand = AlgorandClient.defaultLocalNet() + // You would need to implement getLastWatermark() to retrieve from a persistence store const watermark = await getLastWatermark() const subscription = await getSubscribedTransactions( @@ -357,7 +358,7 @@ const subscription = await getSubscribedTransactions( maxRoundsToSync: 100, onMaxRounds: 'skip-sync-newest', }, - algod, + algorand.client.algod, ) if (transactions.subscribedTransactions.length > 0) { // You would need to implement notifyTransactions to action the transactions @@ -373,7 +374,7 @@ If you ran the following code on a cron schedule of (say) every 5 seconds it wou it would pick up where it left off and catch up using algod (note: you need to connect it to a archival node). ```typescript -const algod = await algokit.getAlgoClient() +const algorand = AlgorandClient.defaultLocalNet() // You would need to implement getLastWatermark() to retrieve from a persistence store const watermark = await getLastWatermark() const subscription = await getSubscribedTransactions( @@ -390,7 +391,7 @@ const subscription = await getSubscribedTransactions( maxRoundsToSync: 100, onMaxRounds: 'sync-oldest-start-now', }, - algod, + algorand.client.algod, ) if (transactions.subscribedTransactions.length > 0) { // You would need to implement notifyTransactions to action the transactions @@ -405,8 +406,7 @@ await saveWatermark(transactions.newWatermark) If you ran the following code on a cron schedule of (say) every 30 - 60 seconds it would create a cached index of all assets created by the account (in this case the Data History Museum TestNet account `ER7AMZRPD5KDVFWTUUVOADSOWM4RQKEEV2EDYRVSA757UHXOIEKGMBQIVU`). Given it uses indexer to catch up you can deploy this into a fresh environment with an empty database and it will catch up in seconds rather than days. ```typescript -const algod = await algokit.getAlgoClient() -const indexer = await algokit.getAlgoIndexerClient() +const algorand = AlgorandClient.defaultLocalNet() // You would need to implement getLastWatermark() to retrieve from a persistence store const watermark = await getLastWatermark() const subscription = await getSubscribedTransactions( @@ -425,8 +425,8 @@ const subscription = await getSubscribedTransactions( maxRoundsToSync: 1000, onMaxRounds: 'catchup-with-indexer', }, - algod, - indexer, + algorand.client.algod, + algorand.client.indexer, ) if (transactions.subscribedTransactions.length > 0) { diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..54f45b0 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,42 @@ +import eslint from '@eslint/js' +import prettier from 'eslint-config-prettier' +import tseslint from 'typescript-eslint' + +export default tseslint.config( + { + ignores: ['.eslint.config.mjs', 'node_modules/**', 'dist/**', 'build/**', 'coverage/**', '**/*.d.ts', '.idea/**', '.vscode/**'], + }, + eslint.configs.recommended, + tseslint.configs.recommended, + { + files: ['**/*.ts'], + languageOptions: { + parser: tseslint.parser, + parserOptions: { + project: './tsconfig.json', + ecmaVersion: 'latest', + sourceType: 'module', + }, + }, + rules: { + 'no-console': 'warn', + '@typescript-eslint/no-unused-vars': [ + 'error', + { ignoreRestSiblings: true, argsIgnorePattern: '^_', destructuredArrayIgnorePattern: '^_', varsIgnorePattern: '^_' }, + ], + '@typescript-eslint/no-unused-expressions': 'off', + 'prefer-template': 'error', + 'no-restricted-syntax': [ + 'error', + { + // Algosdk v2.x.x exports a malformed ES module and when using subscriber-ts in an ESM project + // the CJS module may be loaded, which may not fuly support all named exports. + // The easiest solution for now, is to only use the default export. + message: "Only use the default export in 'algosdk'. See rule comment for details", + selector: 'ImportDeclaration[source.value="algosdk"] ImportSpecifier', + }, + ], + }, + }, + prettier, +) diff --git a/examples/data-history-museum/index.ts b/examples/data-history-museum/index.ts index 85a6312..56c3730 100644 --- a/examples/data-history-museum/index.ts +++ b/examples/data-history-museum/index.ts @@ -1,4 +1,4 @@ -import * as algokit from '@algorandfoundation/algokit-utils' +import { AlgorandClient } from '@algorandfoundation/algokit-utils' import { TransactionResult } from '@algorandfoundation/algokit-utils/types/indexer' import algosdk from 'algosdk' import fs from 'fs' @@ -23,8 +23,8 @@ interface DHMAsset { } async function getDHMSubscriber() { - const algod = await algokit.getAlgoClient() - const indexer = await algokit.getAlgoIndexerClient() + const algorand = AlgorandClient.testNet() + const subscriber = new AlgorandSubscriber( { filters: [ @@ -33,7 +33,7 @@ async function getDHMSubscriber() { filter: { type: TransactionType.acfg, // Data History Museum creator accounts - sender: (await algokit.isTestNet(algod)) + sender: (await algorand.client.isTestNet()) ? 'ER7AMZRPD5KDVFWTUUVOADSOWM4RQKEEV2EDYRVSA757UHXOIEKGMBQIVU' : 'EHYQCYHUC6CIWZLBX5TDTLVJ4SSVE4RRTMKFDCG4Z4Q7QSQ2XWIQPMKBPU', }, @@ -47,8 +47,8 @@ async function getDHMSubscriber() { set: saveWatermark, }, }, - algod, - indexer, + algorand.client.algod, + algorand.client.indexer, ) subscriber.onBatch('dhm-asset', async (events) => { // eslint-disable-next-line no-console diff --git a/examples/usdc/index.ts b/examples/usdc/index.ts index fe20978..e697de2 100644 --- a/examples/usdc/index.ts +++ b/examples/usdc/index.ts @@ -1,4 +1,4 @@ -import * as algokit from '@algorandfoundation/algokit-utils' +import { AlgorandClient } from '@algorandfoundation/algokit-utils' import algosdk from 'algosdk' import fs from 'fs' import path from 'path' @@ -12,7 +12,7 @@ if (!fs.existsSync(path.join(__dirname, '..', '..', '.env')) && !process.env.ALG } ;(async () => { - const algod = await algokit.getAlgoClient() + const algorand = AlgorandClient.testNet() let watermark = 0 const subscriber = new AlgorandSubscriber( @@ -36,7 +36,7 @@ if (!fs.existsSync(path.join(__dirname, '..', '..', '.env')) && !process.env.ALG }, }, }, - algod, + algorand.client.algod, ) subscriber.on('usdc', (transfer) => { // eslint-disable-next-line no-console diff --git a/examples/xgov-voting/index.ts b/examples/xgov-voting/index.ts index f8936cf..41e1aa9 100644 --- a/examples/xgov-voting/index.ts +++ b/examples/xgov-voting/index.ts @@ -1,6 +1,6 @@ import { AlgorandClient } from '@algorandfoundation/algokit-utils' import { Prisma, PrismaClient } from '@prisma/client' -import algosdk, { ABIValue } from 'algosdk' +import algosdk from 'algosdk' import fs from 'fs' import path from 'path' import { AlgorandSubscriber } from '../../src/subscriber' @@ -18,7 +18,7 @@ if (!fs.existsSync(path.join(__dirname, '..', '..', '.env')) && !process.env.ALG const prisma = new PrismaClient() -const votingRoundId = 1821334702 // Grab from https://voting.algorand.foundation/ +const votingRoundId = 1821334702n // Grab from https://voting.algorand.foundation/ const watermarkId = `voting-${votingRoundId}` async function getXGovSubscriber() { @@ -26,9 +26,9 @@ async function getXGovSubscriber() { // Get voting round metadata const appClient = algorand.client.getTypedAppClientById(VotingRoundAppClient, { - id: votingRoundId, + appId: votingRoundId, }) - const votingRoundState = await appClient.getGlobalState() + const votingRoundState = await appClient.state.global.getAll() const votingRoundMetadata = (await ( await fetch(`https://ipfs.algonode.xyz/ipfs/${votingRoundState.metadataIpfsCid!.asString()}`) ).json()) as VotingRoundMetadata @@ -147,7 +147,7 @@ async function getXGovSubscriber() { data: poll.subscribedTransactions.flatMap((t) => { return answerArrayType .decode(Buffer.from(t!['application-transaction']!['application-args']![answerAppArgsIndex], 'base64')) - .map((v: ABIValue, i: number) => { + .map((v: algosdk.ABIValue, i: number) => { if (!useWeighting) { const questionIndex = i const answerIndex = parseInt(v.toString()) diff --git a/examples/xgov-voting/types/voting-app-client.ts b/examples/xgov-voting/types/voting-app-client.ts index 229fd35..5dc98bb 100644 --- a/examples/xgov-voting/types/voting-app-client.ts +++ b/examples/xgov-voting/types/voting-app-client.ts @@ -2,712 +2,345 @@ /** * This file was automatically generated by @algorandfoundation/algokit-client-generator. * DO NOT MODIFY IT BY HAND. - * requires: @algorandfoundation/algokit-utils: ^2 + * requires: @algorandfoundation/algokit-utils: ^7 */ -import * as algokit from '@algorandfoundation/algokit-utils' -import type { - ABIAppCallArg, - AppCallTransactionResult, - AppCallTransactionResultOfType, - AppCompilationResult, - AppReference, - AppState, - AppStorageSchema, - CoreAppCallArgs, - RawAppCallArgs, - TealTemplateParams, -} from '@algorandfoundation/algokit-utils/types/app' -import type { - AppClientCallCoreParams, +import { AlgorandClientInterface } from '@algorandfoundation/algokit-utils/types/algorand-client-interface' +import { ABIReturn, AppReturn, SendAppTransactionResult } from '@algorandfoundation/algokit-utils/types/app' +import { Arc56Contract, getArc56ReturnValue, getABIStructFromABITuple } from '@algorandfoundation/algokit-utils/types/app-arc56' +import { + AppClient as _AppClient, + AppClientMethodCallParams, + AppClientParams, + AppClientBareCallParams, + CallOnComplete, AppClientCompilationParams, - AppClientDeployCoreParams, - AppDetails, - ApplicationClient, + ResolveAppClientByCreatorAndName, + ResolveAppClientByNetwork, + CloneAppClientParams, } from '@algorandfoundation/algokit-utils/types/app-client' -import type { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' -import type { - SendTransactionResult, - TransactionToSign, - SendTransactionFrom, - SendTransactionParams, -} from '@algorandfoundation/algokit-utils/types/transaction' -import type { ABIResult, TransactionWithSigner } from 'algosdk' -import { Algodv2, OnApplicationComplete, Transaction, AtomicTransactionComposer, modelsv2 } from 'algosdk' -export const APP_SPEC: AppSpec = { - hints: { - 'opup_bootstrap(pay)uint64': { - call_config: { - no_op: 'CALL', - }, - }, - 'create(string,uint8,byte[],string,uint64,uint64,uint8[],uint64,string)void': { - call_config: { - no_op: 'CREATE', - }, - }, - 'bootstrap(pay)void': { - call_config: { - no_op: 'CALL', - }, - }, - 'close(application)void': { - default_arguments: { - opup_app: { - source: 'global-state', - data: 'ouaid', - }, - }, - call_config: { - no_op: 'CALL', - }, - }, - 'get_preconditions(byte[],uint64,application)(uint64,uint64,uint64,uint64)': { - read_only: true, - default_arguments: { - opup_app: { - source: 'global-state', - data: 'ouaid', - }, - }, - structs: { - output: { - name: 'VotingPreconditions', - elements: [ - ['is_voting_open', 'uint64'], - ['is_allowed_to_vote', 'uint64'], - ['has_already_voted', 'uint64'], - ['current_time', 'uint64'], - ], - }, - }, - call_config: { - no_op: 'CALL', - }, - }, - 'vote(pay,byte[],uint64,uint8[],uint64[],application)void': { - default_arguments: { - opup_app: { - source: 'global-state', - data: 'ouaid', - }, - }, - call_config: { - no_op: 'CALL', - }, - }, - }, - source: { - approval: - 'I3ByYWdtYSB2ZXJzaW9uIDgKaW50Y2Jsb2NrIDAgMSAxMCAzCmJ5dGVjYmxvY2sgMHg3NjZmNzQ2NTVmNzQ3OTcwNjUgMHggMHg2Zjc1NjE2OTY0IDB4NzY2Zjc0NjU1ZjY5NjQgMHg2ZjcwNzQ2OTZmNmU1ZjYzNmY3NTZlNzQ3MyAweDY5NzM1ZjYyNmY2Zjc0NzM3NDcyNjE3MDcwNjU2NCAweDc2NmY3NDY1NzI1ZjYzNmY3NTZlNzQgMHg2MzZjNmY3MzY1NWY3NDY5NmQ2NSAweDc0NmY3NDYxNmM1ZjZmNzA3NDY5NmY2ZTczIDB4NTYgMHg3MzZlNjE3MDczNjg2Zjc0NWY3MDc1NjI2YzY5NjM1ZjZiNjU3OSAweDZkNjU3NDYxNjQ2MTc0NjE1ZjY5NzA2NjczNWY2MzY5NjQgMHg3Mzc0NjE3Mjc0NWY3NDY5NmQ2NSAweDY1NmU2NDVmNzQ2OTZkNjUgMHg3MTc1NmY3Mjc1NmQgMHg2ZTY2NzQ1ZjY5NmQ2MTY3NjU1Zjc1NzI2YyAweDRjNmJlYTcyIDB4MTUxZjdjNzUgMHg2ZTY2NzQ1ZjYxNzM3MzY1NzQ1ZjY5NjQgMHgwNjgxMDEgMHgyYwp0eG4gTnVtQXBwQXJncwppbnRjXzAgLy8gMAo9PQpibnogbWFpbl9sMTQKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMApwdXNoYnl0ZXMgMHgxMDFjZWEwMCAvLyAib3B1cF9ib290c3RyYXAocGF5KXVpbnQ2NCIKPT0KYm56IG1haW5fbDEzCnR4bmEgQXBwbGljYXRpb25BcmdzIDAKcHVzaGJ5dGVzIDB4NWQ0Y2YwNjYgLy8gImNyZWF0ZShzdHJpbmcsdWludDgsYnl0ZVtdLHN0cmluZyx1aW50NjQsdWludDY0LHVpbnQ4W10sdWludDY0LHN0cmluZyl2b2lkIgo9PQpibnogbWFpbl9sMTIKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMApwdXNoYnl0ZXMgMHhhNGU4ZDE2NCAvLyAiYm9vdHN0cmFwKHBheSl2b2lkIgo9PQpibnogbWFpbl9sMTEKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMApwdXNoYnl0ZXMgMHg5NTQ2ZTEwZiAvLyAiY2xvc2UoYXBwbGljYXRpb24pdm9pZCIKPT0KYm56IG1haW5fbDEwCnR4bmEgQXBwbGljYXRpb25BcmdzIDAKcHVzaGJ5dGVzIDB4MzYzMzA4MjQgLy8gImdldF9wcmVjb25kaXRpb25zKGJ5dGVbXSx1aW50NjQsYXBwbGljYXRpb24pKHVpbnQ2NCx1aW50NjQsdWludDY0LHVpbnQ2NCkiCj09CmJueiBtYWluX2w5CnR4bmEgQXBwbGljYXRpb25BcmdzIDAKcHVzaGJ5dGVzIDB4YzQwZmZkYWEgLy8gInZvdGUocGF5LGJ5dGVbXSx1aW50NjQsdWludDhbXSx1aW50NjRbXSxhcHBsaWNhdGlvbil2b2lkIgo9PQpibnogbWFpbl9sOAplcnIKbWFpbl9sODoKdHhuIE9uQ29tcGxldGlvbgppbnRjXzAgLy8gTm9PcAo9PQp0eG4gQXBwbGljYXRpb25JRAppbnRjXzAgLy8gMAohPQomJgphc3NlcnQKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQpzdG9yZSAxNwp0eG5hIEFwcGxpY2F0aW9uQXJncyAyCmJ0b2kKc3RvcmUgMTgKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwpzdG9yZSAxOQp0eG5hIEFwcGxpY2F0aW9uQXJncyA0CnN0b3JlIDIwCnR4bmEgQXBwbGljYXRpb25BcmdzIDUKaW50Y18wIC8vIDAKZ2V0Ynl0ZQpzdG9yZSAyMQp0eG4gR3JvdXBJbmRleAppbnRjXzEgLy8gMQotCnN0b3JlIDE2CmxvYWQgMTYKZ3R4bnMgVHlwZUVudW0KaW50Y18xIC8vIHBheQo9PQphc3NlcnQKbG9hZCAxNgpsb2FkIDE3CmxvYWQgMTgKbG9hZCAxOQpsb2FkIDIwCmxvYWQgMjEKY2FsbHN1YiB2b3RlXzEyCmludGNfMSAvLyAxCnJldHVybgptYWluX2w5Ogp0eG4gT25Db21wbGV0aW9uCmludGNfMCAvLyBOb09wCj09CnR4biBBcHBsaWNhdGlvbklECmludGNfMCAvLyAwCiE9CiYmCmFzc2VydAp0eG5hIEFwcGxpY2F0aW9uQXJncyAxCnN0b3JlIDEyCnR4bmEgQXBwbGljYXRpb25BcmdzIDIKYnRvaQpzdG9yZSAxMwp0eG5hIEFwcGxpY2F0aW9uQXJncyAzCmludGNfMCAvLyAwCmdldGJ5dGUKc3RvcmUgMTQKbG9hZCAxMgpsb2FkIDEzCmxvYWQgMTQKY2FsbHN1YiBnZXRwcmVjb25kaXRpb25zXzExCnN0b3JlIDE1CmJ5dGVjIDE3IC8vIDB4MTUxZjdjNzUKbG9hZCAxNQpjb25jYXQKbG9nCmludGNfMSAvLyAxCnJldHVybgptYWluX2wxMDoKdHhuIE9uQ29tcGxldGlvbgppbnRjXzAgLy8gTm9PcAo9PQp0eG4gQXBwbGljYXRpb25JRAppbnRjXzAgLy8gMAohPQomJgphc3NlcnQKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQppbnRjXzAgLy8gMApnZXRieXRlCmNhbGxzdWIgY2xvc2VfNwppbnRjXzEgLy8gMQpyZXR1cm4KbWFpbl9sMTE6CnR4biBPbkNvbXBsZXRpb24KaW50Y18wIC8vIE5vT3AKPT0KdHhuIEFwcGxpY2F0aW9uSUQKaW50Y18wIC8vIDAKIT0KJiYKYXNzZXJ0CnR4biBHcm91cEluZGV4CmludGNfMSAvLyAxCi0Kc3RvcmUgMTEKbG9hZCAxMQpndHhucyBUeXBlRW51bQppbnRjXzEgLy8gcGF5Cj09CmFzc2VydApsb2FkIDExCmNhbGxzdWIgYm9vdHN0cmFwXzYKaW50Y18xIC8vIDEKcmV0dXJuCm1haW5fbDEyOgp0eG4gT25Db21wbGV0aW9uCmludGNfMCAvLyBOb09wCj09CnR4biBBcHBsaWNhdGlvbklECmludGNfMCAvLyAwCj09CiYmCmFzc2VydAp0eG5hIEFwcGxpY2F0aW9uQXJncyAxCnN0b3JlIDIKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgppbnRjXzAgLy8gMApnZXRieXRlCnN0b3JlIDMKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwpzdG9yZSA0CnR4bmEgQXBwbGljYXRpb25BcmdzIDQKc3RvcmUgNQp0eG5hIEFwcGxpY2F0aW9uQXJncyA1CmJ0b2kKc3RvcmUgNgp0eG5hIEFwcGxpY2F0aW9uQXJncyA2CmJ0b2kKc3RvcmUgNwp0eG5hIEFwcGxpY2F0aW9uQXJncyA3CnN0b3JlIDgKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgOApidG9pCnN0b3JlIDkKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgOQpzdG9yZSAxMApsb2FkIDIKbG9hZCAzCmxvYWQgNApsb2FkIDUKbG9hZCA2CmxvYWQgNwpsb2FkIDgKbG9hZCA5CmxvYWQgMTAKY2FsbHN1YiBjcmVhdGVfNQppbnRjXzEgLy8gMQpyZXR1cm4KbWFpbl9sMTM6CnR4biBPbkNvbXBsZXRpb24KaW50Y18wIC8vIE5vT3AKPT0KdHhuIEFwcGxpY2F0aW9uSUQKaW50Y18wIC8vIDAKIT0KJiYKYXNzZXJ0CnR4biBHcm91cEluZGV4CmludGNfMSAvLyAxCi0Kc3RvcmUgMApsb2FkIDAKZ3R4bnMgVHlwZUVudW0KaW50Y18xIC8vIHBheQo9PQphc3NlcnQKbG9hZCAwCmNhbGxzdWIgb3B1cGJvb3RzdHJhcF8zCnN0b3JlIDEKYnl0ZWMgMTcgLy8gMHgxNTFmN2M3NQpsb2FkIDEKaXRvYgpjb25jYXQKbG9nCmludGNfMSAvLyAxCnJldHVybgptYWluX2wxNDoKdHhuIE9uQ29tcGxldGlvbgpwdXNoaW50IDUgLy8gRGVsZXRlQXBwbGljYXRpb24KPT0KYm56IG1haW5fbDE2CmVycgptYWluX2wxNjoKdHhuIEFwcGxpY2F0aW9uSUQKaW50Y18wIC8vIDAKIT0KYXNzZXJ0CmNhbGxzdWIgZGVsZXRlXzIKaW50Y18xIC8vIDEKcmV0dXJuCgovLyBpbnRfdG9fYXNjaWkKaW50dG9hc2NpaV8wOgpwcm90byAxIDEKcHVzaGJ5dGVzIDB4MzAzMTMyMzMzNDM1MzYzNzM4MzkgLy8gIjAxMjM0NTY3ODkiCmZyYW1lX2RpZyAtMQppbnRjXzEgLy8gMQpleHRyYWN0MwpyZXRzdWIKCi8vIGl0b2EKaXRvYV8xOgpwcm90byAxIDEKZnJhbWVfZGlnIC0xCmludGNfMCAvLyAwCj09CmJueiBpdG9hXzFfbDUKZnJhbWVfZGlnIC0xCmludGNfMiAvLyAxMAovCmludGNfMCAvLyAwCj4KYm56IGl0b2FfMV9sNApieXRlY18xIC8vICIiCml0b2FfMV9sMzoKZnJhbWVfZGlnIC0xCmludGNfMiAvLyAxMAolCmNhbGxzdWIgaW50dG9hc2NpaV8wCmNvbmNhdApiIGl0b2FfMV9sNgppdG9hXzFfbDQ6CmZyYW1lX2RpZyAtMQppbnRjXzIgLy8gMTAKLwpjYWxsc3ViIGl0b2FfMQpiIGl0b2FfMV9sMwppdG9hXzFfbDU6CnB1c2hieXRlcyAweDMwIC8vICIwIgppdG9hXzFfbDY6CnJldHN1YgoKLy8gZGVsZXRlCmRlbGV0ZV8yOgpwcm90byAwIDAKdHhuIFNlbmRlcgpnbG9iYWwgQ3JlYXRvckFkZHJlc3MKPT0KLy8gdW5hdXRob3JpemVkCmFzc2VydApwdXNoaW50IFRNUExfREVMRVRBQkxFIC8vIFRNUExfREVMRVRBQkxFCi8vIENoZWNrIGFwcCBpcyBkZWxldGFibGUKYXNzZXJ0CnJldHN1YgoKLy8gb3B1cF9ib290c3RyYXAKb3B1cGJvb3RzdHJhcF8zOgpwcm90byAxIDEKaW50Y18wIC8vIDAKZnJhbWVfZGlnIC0xCmd0eG5zIEFtb3VudApwdXNoaW50IDEwMDAwMCAvLyAxMDAwMDAKPj0KYXNzZXJ0CmNhbGxzdWIgY3JlYXRlb3B1cF80CmJ5dGVjXzIgLy8gIm91YWlkIgphcHBfZ2xvYmFsX2dldApmcmFtZV9idXJ5IDAKcmV0c3ViCgovLyBjcmVhdGVfb3B1cApjcmVhdGVvcHVwXzQ6CnByb3RvIDAgMAppdHhuX2JlZ2luCnB1c2hpbnQgNiAvLyBhcHBsCml0eG5fZmllbGQgVHlwZUVudW0KcHVzaGJ5dGVzIDB4MDgyMDAyMDAwMTMxMWIyMjEyNDAwMDFkMzYxYTAwODAwNDRjNmJlYTcyMTI0MDAwMDEwMDMxMTkyMjEyMzExODIyMTMxMDQ0ODgwMDExMjM0MzMxMTkyMjEyNDAwMDAxMDAzMTE4MjIxMjQ0MjM0MzhhMDAwMDMxMDAzMjA5MTI0NDIzNDMgLy8gMHgwODIwMDIwMDAxMzExYjIyMTI0MDAwMWQzNjFhMDA4MDA0NGM2YmVhNzIxMjQwMDAwMTAwMzExOTIyMTIzMTE4MjIxMzEwNDQ4ODAwMTEyMzQzMzExOTIyMTI0MDAwMDEwMDMxMTgyMjEyNDQyMzQzOGEwMDAwMzEwMDMyMDkxMjQ0MjM0MwppdHhuX2ZpZWxkIEFwcHJvdmFsUHJvZ3JhbQpwdXNoYnl0ZXMgMHgwODgxMDA0MyAvLyAweDA4ODEwMDQzCml0eG5fZmllbGQgQ2xlYXJTdGF0ZVByb2dyYW0KaW50Y18wIC8vIDAKaXR4bl9maWVsZCBGZWUKaXR4bl9zdWJtaXQKaW50Y18wIC8vIDAKYnl0ZWNfMiAvLyAib3VhaWQiCmFwcF9nbG9iYWxfZ2V0X2V4CnN0b3JlIDIzCnN0b3JlIDIyCmxvYWQgMjMKIQphc3NlcnQKYnl0ZWNfMiAvLyAib3VhaWQiCml0eG4gQ3JlYXRlZEFwcGxpY2F0aW9uSUQKYXBwX2dsb2JhbF9wdXQKcmV0c3ViCgovLyBjcmVhdGUKY3JlYXRlXzU6CnByb3RvIDkgMAppbnRjXzAgLy8gMApkdXAKYnl0ZWNfMSAvLyAiIgppbnRjXzAgLy8gMApkdXBuIDIKZnJhbWVfZGlnIC01CmZyYW1lX2RpZyAtNAo8PQovLyBFbmQgdGltZSBzaG91bGQgYmUgYWZ0ZXIgc3RhcnQgdGltZQphc3NlcnQKZnJhbWVfZGlnIC00Cmdsb2JhbCBMYXRlc3RUaW1lc3RhbXAKPj0KLy8gRW5kIHRpbWUgc2hvdWxkIGJlIGluIHRoZSBmdXR1cmUKYXNzZXJ0CmZyYW1lX2RpZyAtOAppbnRjXzMgLy8gMwo8PQovLyBWb3RlIHR5cGUgc2hvdWxkIGJlIDw9IDMKYXNzZXJ0CmludGNfMCAvLyAwCmJ5dGVjXzMgLy8gInZvdGVfaWQiCmFwcF9nbG9iYWxfZ2V0X2V4CnN0b3JlIDI1CnN0b3JlIDI0CmxvYWQgMjUKIQphc3NlcnQKYnl0ZWNfMyAvLyAidm90ZV9pZCIKZnJhbWVfZGlnIC05CmV4dHJhY3QgMiAwCmFwcF9nbG9iYWxfcHV0CmludGNfMCAvLyAwCmJ5dGVjXzAgLy8gInZvdGVfdHlwZSIKYXBwX2dsb2JhbF9nZXRfZXgKc3RvcmUgMjcKc3RvcmUgMjYKbG9hZCAyNwohCmFzc2VydApieXRlY18wIC8vICJ2b3RlX3R5cGUiCmZyYW1lX2RpZyAtOAphcHBfZ2xvYmFsX3B1dAppbnRjXzAgLy8gMApieXRlYyAxMCAvLyAic25hcHNob3RfcHVibGljX2tleSIKYXBwX2dsb2JhbF9nZXRfZXgKc3RvcmUgMjkKc3RvcmUgMjgKbG9hZCAyOQohCmFzc2VydApieXRlYyAxMCAvLyAic25hcHNob3RfcHVibGljX2tleSIKZnJhbWVfZGlnIC03CmV4dHJhY3QgMiAwCmFwcF9nbG9iYWxfcHV0CmludGNfMCAvLyAwCmJ5dGVjIDExIC8vICJtZXRhZGF0YV9pcGZzX2NpZCIKYXBwX2dsb2JhbF9nZXRfZXgKc3RvcmUgMzEKc3RvcmUgMzAKbG9hZCAzMQohCmFzc2VydApieXRlYyAxMSAvLyAibWV0YWRhdGFfaXBmc19jaWQiCmZyYW1lX2RpZyAtNgpleHRyYWN0IDIgMAphcHBfZ2xvYmFsX3B1dAppbnRjXzAgLy8gMApieXRlYyAxMiAvLyAic3RhcnRfdGltZSIKYXBwX2dsb2JhbF9nZXRfZXgKc3RvcmUgMzMKc3RvcmUgMzIKbG9hZCAzMwohCmFzc2VydApieXRlYyAxMiAvLyAic3RhcnRfdGltZSIKZnJhbWVfZGlnIC01CmFwcF9nbG9iYWxfcHV0CmludGNfMCAvLyAwCmJ5dGVjIDEzIC8vICJlbmRfdGltZSIKYXBwX2dsb2JhbF9nZXRfZXgKc3RvcmUgMzUKc3RvcmUgMzQKbG9hZCAzNQohCmFzc2VydApieXRlYyAxMyAvLyAiZW5kX3RpbWUiCmZyYW1lX2RpZyAtNAphcHBfZ2xvYmFsX3B1dAppbnRjXzAgLy8gMApieXRlYyAxNCAvLyAicXVvcnVtIgphcHBfZ2xvYmFsX2dldF9leApzdG9yZSAzNwpzdG9yZSAzNgpsb2FkIDM3CiEKYXNzZXJ0CmJ5dGVjIDE0IC8vICJxdW9ydW0iCmZyYW1lX2RpZyAtMgphcHBfZ2xvYmFsX3B1dApieXRlYyA1IC8vICJpc19ib290c3RyYXBwZWQiCmludGNfMCAvLyAwCmFwcF9nbG9iYWxfcHV0CmJ5dGVjIDYgLy8gInZvdGVyX2NvdW50IgppbnRjXzAgLy8gMAphcHBfZ2xvYmFsX3B1dApieXRlYyA3IC8vICJjbG9zZV90aW1lIgppbnRjXzAgLy8gMAphcHBfZ2xvYmFsX3B1dAppbnRjXzAgLy8gMApieXRlYyAxNSAvLyAibmZ0X2ltYWdlX3VybCIKYXBwX2dsb2JhbF9nZXRfZXgKc3RvcmUgMzkKc3RvcmUgMzgKbG9hZCAzOQohCmFzc2VydApieXRlYyAxNSAvLyAibmZ0X2ltYWdlX3VybCIKZnJhbWVfZGlnIC0xCmV4dHJhY3QgMiAwCmFwcF9nbG9iYWxfcHV0CmJ5dGVjIDE4IC8vICJuZnRfYXNzZXRfaWQiCmludGNfMCAvLyAwCmFwcF9nbG9iYWxfcHV0CmZyYW1lX2RpZyAtMwppbnRjXzAgLy8gMApleHRyYWN0X3VpbnQxNgpmcmFtZV9idXJ5IDAKZnJhbWVfZGlnIDAKLy8gb3B0aW9uX2NvdW50cyBzaG91bGQgYmUgbm9uLWVtcHR5CmFzc2VydApmcmFtZV9kaWcgLTMKaW50Y18wIC8vIDAKZXh0cmFjdF91aW50MTYKZnJhbWVfYnVyeSAxCmZyYW1lX2RpZyAxCnB1c2hpbnQgMTEyIC8vIDExMgo8PQovLyBDYW4ndCBoYXZlIG1vcmUgdGhhbiAxMTIgcXVlc3Rpb25zCmFzc2VydAppbnRjXzAgLy8gMApieXRlYyA0IC8vICJvcHRpb25fY291bnRzIgphcHBfZ2xvYmFsX2dldF9leApzdG9yZSA0MQpzdG9yZSA0MApsb2FkIDQxCiEKYXNzZXJ0CmJ5dGVjIDQgLy8gIm9wdGlvbl9jb3VudHMiCmZyYW1lX2RpZyAtMwphcHBfZ2xvYmFsX3B1dApieXRlYyA0IC8vICJvcHRpb25fY291bnRzIgphcHBfZ2xvYmFsX2dldApmcmFtZV9idXJ5IDIKaW50Y18wIC8vIDAKc3RvcmUgNDMKZnJhbWVfZGlnIDIKaW50Y18wIC8vIDAKZXh0cmFjdF91aW50MTYKZnJhbWVfYnVyeSAzCmZyYW1lX2RpZyAzCnN0b3JlIDQ0CmludGNfMCAvLyAwCnN0b3JlIDQ1CmNyZWF0ZV81X2wxOgpsb2FkIDQ1CmxvYWQgNDQKPApieiBjcmVhdGVfNV9sNwpnbG9iYWwgT3Bjb2RlQnVkZ2V0CnB1c2hpbnQgMTAwIC8vIDEwMAo8CmJueiBjcmVhdGVfNV9sNApjcmVhdGVfNV9sMzoKZnJhbWVfZGlnIDIKaW50Y18xIC8vIDEKbG9hZCA0NQoqCnB1c2hpbnQgMiAvLyAyCisKZ2V0Ynl0ZQpmcmFtZV9idXJ5IDQKbG9hZCA0MwpmcmFtZV9kaWcgNAorCnN0b3JlIDQzCmxvYWQgNDUKaW50Y18xIC8vIDEKKwpzdG9yZSA0NQpiIGNyZWF0ZV81X2wxCmNyZWF0ZV81X2w0OgpwdXNoaW50IDYwMCAvLyA2MDAKaW50Y18yIC8vIDEwCisKc3RvcmUgNDYKY3JlYXRlXzVfbDU6CmxvYWQgNDYKZ2xvYmFsIE9wY29kZUJ1ZGdldAo+CmJ6IGNyZWF0ZV81X2wzCml0eG5fYmVnaW4KcHVzaGludCA2IC8vIGFwcGwKaXR4bl9maWVsZCBUeXBlRW51bQppbnRjXzAgLy8gMAppdHhuX2ZpZWxkIEZlZQpwdXNoaW50IDUgLy8gRGVsZXRlQXBwbGljYXRpb24KaXR4bl9maWVsZCBPbkNvbXBsZXRpb24KYnl0ZWMgMTkgLy8gMHgwNjgxMDEKaXR4bl9maWVsZCBBcHByb3ZhbFByb2dyYW0KYnl0ZWMgMTkgLy8gMHgwNjgxMDEKaXR4bl9maWVsZCBDbGVhclN0YXRlUHJvZ3JhbQppdHhuX3N1Ym1pdApiIGNyZWF0ZV81X2w1CmNyZWF0ZV81X2w3Ogpsb2FkIDQzCnN0b3JlIDQyCmxvYWQgNDIKcHVzaGludCAxMjggLy8gMTI4Cjw9Ci8vIENhbid0IGhhdmUgbW9yZSB0aGFuIDEyOCB2b3RlIG9wdGlvbnMKYXNzZXJ0CmludGNfMCAvLyAwCmJ5dGVjIDggLy8gInRvdGFsX29wdGlvbnMiCmFwcF9nbG9iYWxfZ2V0X2V4CnN0b3JlIDQ4CnN0b3JlIDQ3CmxvYWQgNDgKIQphc3NlcnQKYnl0ZWMgOCAvLyAidG90YWxfb3B0aW9ucyIKbG9hZCA0MgphcHBfZ2xvYmFsX3B1dApyZXRzdWIKCi8vIGJvb3RzdHJhcApib290c3RyYXBfNjoKcHJvdG8gMSAwCmludGNfMCAvLyAwCnR4biBTZW5kZXIKZ2xvYmFsIENyZWF0b3JBZGRyZXNzCj09Ci8vIHVuYXV0aG9yaXplZAphc3NlcnQKYnl0ZWMgNSAvLyAiaXNfYm9vdHN0cmFwcGVkIgphcHBfZ2xvYmFsX2dldAohCi8vIEFscmVhZHkgYm9vdHN0cmFwcGVkCmFzc2VydApieXRlYyA1IC8vICJpc19ib290c3RyYXBwZWQiCmludGNfMSAvLyAxCmFwcF9nbG9iYWxfcHV0CnB1c2hpbnQgMzAzOTAwIC8vIDMwMzkwMApieXRlYyA4IC8vICJ0b3RhbF9vcHRpb25zIgphcHBfZ2xvYmFsX2dldApwdXNoaW50IDMyMDAgLy8gMzIwMAoqCisKc3RvcmUgNDkKZnJhbWVfZGlnIC0xCmd0eG5zIFJlY2VpdmVyCmdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCj09Ci8vIFBheW1lbnQgbXVzdCBiZSB0byBhcHAgYWRkcmVzcwphc3NlcnQKbG9hZCA0OQppdG9iCmxvZwpmcmFtZV9kaWcgLTEKZ3R4bnMgQW1vdW50CmxvYWQgNDkKPT0KLy8gUGF5bWVudCBtdXN0IGJlIGZvciB0aGUgZXhhY3QgbWluIGJhbGFuY2UgcmVxdWlyZW1lbnQKYXNzZXJ0CmJ5dGVjIDkgLy8gIlYiCmJ5dGVjIDggLy8gInRvdGFsX29wdGlvbnMiCmFwcF9nbG9iYWxfZ2V0CnB1c2hpbnQgOCAvLyA4CioKYm94X2NyZWF0ZQpwb3AKY2FsbHN1YiBjcmVhdGVvcHVwXzQKcmV0c3ViCgovLyBjbG9zZQpjbG9zZV83Ogpwcm90byAxIDAKYnl0ZWNfMSAvLyAiIgppbnRjXzAgLy8gMApkdXBuIDIKdHhuIFNlbmRlcgpnbG9iYWwgQ3JlYXRvckFkZHJlc3MKPT0KLy8gdW5hdXRob3JpemVkCmFzc2VydApmcmFtZV9kaWcgLTEKdHhuYXMgQXBwbGljYXRpb25zCmJ5dGVjXzIgLy8gIm91YWlkIgphcHBfZ2xvYmFsX2dldAo9PQovLyBPcFVwIGFwcCBJRCBub3QgcGFzc2VkIGluCmFzc2VydApwdXNoaW50IDIwMDAwIC8vIDIwMDAwCmludGNfMiAvLyAxMAorCnN0b3JlIDUwCmNsb3NlXzdfbDE6CmxvYWQgNTAKZ2xvYmFsIE9wY29kZUJ1ZGdldAo+CmJueiBjbG9zZV83X2wxNwpieXRlYyA3IC8vICJjbG9zZV90aW1lIgphcHBfZ2xvYmFsX2dldAppbnRjXzAgLy8gMAo9PQovLyBBbHJlYWR5IGNsb3NlZAphc3NlcnQKYnl0ZWMgNyAvLyAiY2xvc2VfdGltZSIKZ2xvYmFsIExhdGVzdFRpbWVzdGFtcAphcHBfZ2xvYmFsX3B1dApwdXNoYnl0ZXMgMHg3YjIyNzM3NDYxNmU2NDYxNzI2NDIyM2EyMjYxNzI2MzM2MzkyMjJjMjI2NDY1NzM2MzcyNjk3MDc0Njk2ZjZlMjIzYTIyNTQ2ODY5NzMyMDY5NzMyMDYxMjA3NjZmNzQ2OTZlNjcyMDcyNjU3Mzc1NmM3NDIwNGU0NjU0MjA2NjZmNzIyMDc2NmY3NDY5NmU2NzIwNzI2Zjc1NmU2NDIwNzc2OTc0NjgyMDQ5NDQyMCAvLyAie1wic3RhbmRhcmRcIjpcImFyYzY5XCIsXCJkZXNjcmlwdGlvblwiOlwiVGhpcyBpcyBhIHZvdGluZyByZXN1bHQgTkZUIGZvciB2b3Rpbmcgcm91bmQgd2l0aCBJRCAiCmJ5dGVjXzMgLy8gInZvdGVfaWQiCmFwcF9nbG9iYWxfZ2V0CmNvbmNhdApwdXNoYnl0ZXMgMHgyZTIyMmMyMjcwNzI2ZjcwNjU3Mjc0Njk2NTczMjIzYTdiMjI2ZDY1NzQ2MTY0NjE3NDYxMjIzYTIyNjk3MDY2NzMzYTJmMmYgLy8gIi5cIixcInByb3BlcnRpZXNcIjp7XCJtZXRhZGF0YVwiOlwiaXBmczovLyIKY29uY2F0CmJ5dGVjIDExIC8vICJtZXRhZGF0YV9pcGZzX2NpZCIKYXBwX2dsb2JhbF9nZXQKY29uY2F0CnB1c2hieXRlcyAweDIyMmMyMjY5NjQyMjNhMjIgLy8gIlwiLFwiaWRcIjpcIiIKY29uY2F0CmJ5dGVjXzMgLy8gInZvdGVfaWQiCmFwcF9nbG9iYWxfZ2V0CmNvbmNhdApwdXNoYnl0ZXMgMHgyMjJjMjI3MTc1NmY3Mjc1NmQyMjNhIC8vICJcIixcInF1b3J1bVwiOiIKY29uY2F0CmJ5dGVjIDE0IC8vICJxdW9ydW0iCmFwcF9nbG9iYWxfZ2V0CmNhbGxzdWIgaXRvYV8xCmNvbmNhdApwdXNoYnl0ZXMgMHgyYzIyNzY2Zjc0NjU3MjQzNmY3NTZlNzQyMjNhIC8vICIsXCJ2b3RlckNvdW50XCI6Igpjb25jYXQKYnl0ZWMgNiAvLyAidm90ZXJfY291bnQiCmFwcF9nbG9iYWxfZ2V0CmNhbGxzdWIgaXRvYV8xCmNvbmNhdApwdXNoYnl0ZXMgMHgyYzIyNzQ2MTZjNmM2OTY1NzMyMjNhNWIgLy8gIixcInRhbGxpZXNcIjpbIgpjb25jYXQKc3RvcmUgNTEKYnl0ZWMgNCAvLyAib3B0aW9uX2NvdW50cyIKYXBwX2dsb2JhbF9nZXQKZnJhbWVfYnVyeSAwCmZyYW1lX2RpZyAwCmludGNfMCAvLyAwCmV4dHJhY3RfdWludDE2CmZyYW1lX2J1cnkgMQpmcmFtZV9kaWcgMQpzdG9yZSA1MgppbnRjXzAgLy8gMApzdG9yZSA1MwppbnRjXzAgLy8gMApzdG9yZSA1NAppbnRjXzAgLy8gMApzdG9yZSA1NQpjbG9zZV83X2wzOgpsb2FkIDU1CmxvYWQgNTIKPApieiBjbG9zZV83X2wxOApmcmFtZV9kaWcgMAppbnRjXzEgLy8gMQpsb2FkIDU1CioKcHVzaGludCAyIC8vIDIKKwpnZXRieXRlCmZyYW1lX2J1cnkgMgpmcmFtZV9kaWcgMgpzdG9yZSA1NgppbnRjXzAgLy8gMApzdG9yZSA1NwpjbG9zZV83X2w1Ogpsb2FkIDU3CmxvYWQgNTYKPApibnogY2xvc2VfN19sNwpsb2FkIDU1CmludGNfMSAvLyAxCisKc3RvcmUgNTUKYiBjbG9zZV83X2wzCmNsb3NlXzdfbDc6CnB1c2hpbnQgOCAvLyA4CmxvYWQgNTQKKgpzdG9yZSA1OApieXRlYyA5IC8vICJWIgpsb2FkIDU4CnB1c2hpbnQgOCAvLyA4CmJveF9leHRyYWN0CmJ0b2kKc3RvcmUgNTMKbG9hZCA1MQpsb2FkIDU3CmludGNfMCAvLyAwCj09CmJueiBjbG9zZV83X2wxNgpieXRlY18xIC8vICIiCmNsb3NlXzdfbDk6CmNvbmNhdApsb2FkIDUzCmNhbGxzdWIgaXRvYV8xCmNvbmNhdApsb2FkIDU3CmxvYWQgNTYKaW50Y18xIC8vIDEKLQo9PQpibnogY2xvc2VfN19sMTIKYnl0ZWMgMjAgLy8gIiwiCmNsb3NlXzdfbDExOgpjb25jYXQKc3RvcmUgNTEKbG9hZCA1NAppbnRjXzEgLy8gMQorCnN0b3JlIDU0CmxvYWQgNTcKaW50Y18xIC8vIDEKKwpzdG9yZSA1NwpiIGNsb3NlXzdfbDUKY2xvc2VfN19sMTI6CnB1c2hieXRlcyAweDVkIC8vICJdIgpsb2FkIDU1CmxvYWQgNTIKaW50Y18xIC8vIDEKLQo9PQpibnogY2xvc2VfN19sMTUKYnl0ZWMgMjAgLy8gIiwiCmNsb3NlXzdfbDE0Ogpjb25jYXQKYiBjbG9zZV83X2wxMQpjbG9zZV83X2wxNToKYnl0ZWNfMSAvLyAiIgpiIGNsb3NlXzdfbDE0CmNsb3NlXzdfbDE2OgpwdXNoYnl0ZXMgMHg1YiAvLyAiWyIKYiBjbG9zZV83X2w5CmNsb3NlXzdfbDE3OgppdHhuX2JlZ2luCnB1c2hpbnQgNiAvLyBhcHBsCml0eG5fZmllbGQgVHlwZUVudW0KYnl0ZWNfMiAvLyAib3VhaWQiCmFwcF9nbG9iYWxfZ2V0Cml0eG5fZmllbGQgQXBwbGljYXRpb25JRApieXRlYyAxNiAvLyAib3B1cCgpdm9pZCIKaXR4bl9maWVsZCBBcHBsaWNhdGlvbkFyZ3MKaW50Y18wIC8vIDAKaXR4bl9maWVsZCBGZWUKaXR4bl9zdWJtaXQKYiBjbG9zZV83X2wxCmNsb3NlXzdfbDE4OgppdHhuX2JlZ2luCmludGNfMyAvLyBhY2ZnCml0eG5fZmllbGQgVHlwZUVudW0KaW50Y18xIC8vIDEKaXR4bl9maWVsZCBDb25maWdBc3NldFRvdGFsCmludGNfMCAvLyAwCml0eG5fZmllbGQgQ29uZmlnQXNzZXREZWNpbWFscwppbnRjXzAgLy8gMAppdHhuX2ZpZWxkIENvbmZpZ0Fzc2V0RGVmYXVsdEZyb3plbgpwdXNoYnl0ZXMgMHg1YjU2NGY1NDQ1MjA1MjQ1NTM1NTRjNTQ1ZDIwIC8vICJbVk9URSBSRVNVTFRdICIKYnl0ZWNfMyAvLyAidm90ZV9pZCIKYXBwX2dsb2JhbF9nZXQKY29uY2F0Cml0eG5fZmllbGQgQ29uZmlnQXNzZXROYW1lCnB1c2hieXRlcyAweDU2NGY1NDQ1NTI1MzRjNTQgLy8gIlZPVEVSU0xUIgppdHhuX2ZpZWxkIENvbmZpZ0Fzc2V0VW5pdE5hbWUKYnl0ZWMgMTUgLy8gIm5mdF9pbWFnZV91cmwiCmFwcF9nbG9iYWxfZ2V0Cml0eG5fZmllbGQgQ29uZmlnQXNzZXRVUkwKbG9hZCA1MQpwdXNoYnl0ZXMgMHg1ZDdkN2QgLy8gIl19fSIKY29uY2F0Cml0eG5fZmllbGQgTm90ZQppdHhuX3N1Ym1pdApieXRlYyAxOCAvLyAibmZ0X2Fzc2V0X2lkIgppdHhuIENyZWF0ZWRBc3NldElECmFwcF9nbG9iYWxfcHV0CnJldHN1YgoKLy8gYWxsb3dlZF90b192b3RlCmFsbG93ZWR0b3ZvdGVfODoKcHJvdG8gMyAxCmJ5dGVjXzAgLy8gInZvdGVfdHlwZSIKYXBwX2dsb2JhbF9nZXQKaW50Y18wIC8vIDAKPT0KYm56IGFsbG93ZWR0b3ZvdGVfOF9sOApmcmFtZV9kaWcgLTEKdHhuYXMgQXBwbGljYXRpb25zCmJ5dGVjXzIgLy8gIm91YWlkIgphcHBfZ2xvYmFsX2dldAo9PQovLyBPcFVwIGFwcCBJRCBub3QgcGFzc2VkIGluCmFzc2VydApwdXNoaW50IDIwMDAgLy8gMjAwMAppbnRjXzIgLy8gMTAKKwpzdG9yZSA1OQphbGxvd2VkdG92b3RlXzhfbDI6CmxvYWQgNTkKZ2xvYmFsIE9wY29kZUJ1ZGdldAo+CmJueiBhbGxvd2VkdG92b3RlXzhfbDcKYnl0ZWNfMCAvLyAidm90ZV90eXBlIgphcHBfZ2xvYmFsX2dldAppbnRjXzEgLy8gMQo9PQpibnogYWxsb3dlZHRvdm90ZV84X2w2CnR4biBTZW5kZXIKZnJhbWVfZGlnIC0yCml0b2IKY29uY2F0CmFsbG93ZWR0b3ZvdGVfOF9sNToKZnJhbWVfZGlnIC0zCmJ5dGVjIDEwIC8vICJzbmFwc2hvdF9wdWJsaWNfa2V5IgphcHBfZ2xvYmFsX2dldAplZDI1NTE5dmVyaWZ5X2JhcmUKYiBhbGxvd2VkdG92b3RlXzhfbDkKYWxsb3dlZHRvdm90ZV84X2w2Ogp0eG4gU2VuZGVyCmIgYWxsb3dlZHRvdm90ZV84X2w1CmFsbG93ZWR0b3ZvdGVfOF9sNzoKaXR4bl9iZWdpbgpwdXNoaW50IDYgLy8gYXBwbAppdHhuX2ZpZWxkIFR5cGVFbnVtCmJ5dGVjXzIgLy8gIm91YWlkIgphcHBfZ2xvYmFsX2dldAppdHhuX2ZpZWxkIEFwcGxpY2F0aW9uSUQKYnl0ZWMgMTYgLy8gIm9wdXAoKXZvaWQiCml0eG5fZmllbGQgQXBwbGljYXRpb25BcmdzCmludGNfMCAvLyAwCml0eG5fZmllbGQgRmVlCml0eG5fc3VibWl0CmIgYWxsb3dlZHRvdm90ZV84X2wyCmFsbG93ZWR0b3ZvdGVfOF9sODoKaW50Y18xIC8vIDEKYWxsb3dlZHRvdm90ZV84X2w5OgpyZXRzdWIKCi8vIHZvdGluZ19vcGVuCnZvdGluZ29wZW5fOToKcHJvdG8gMCAxCmJ5dGVjIDUgLy8gImlzX2Jvb3RzdHJhcHBlZCIKYXBwX2dsb2JhbF9nZXQKaW50Y18xIC8vIDEKPT0KYnl0ZWMgNyAvLyAiY2xvc2VfdGltZSIKYXBwX2dsb2JhbF9nZXQKaW50Y18wIC8vIDAKPT0KJiYKZ2xvYmFsIExhdGVzdFRpbWVzdGFtcApieXRlYyAxMiAvLyAic3RhcnRfdGltZSIKYXBwX2dsb2JhbF9nZXQKPj0KJiYKZ2xvYmFsIExhdGVzdFRpbWVzdGFtcApieXRlYyAxMyAvLyAiZW5kX3RpbWUiCmFwcF9nbG9iYWxfZ2V0CjwKJiYKcmV0c3ViCgovLyBhbHJlYWR5X3ZvdGVkCmFscmVhZHl2b3RlZF8xMDoKcHJvdG8gMCAxCmJ5dGVjXzEgLy8gIiIKdHhuIFNlbmRlcgpmcmFtZV9idXJ5IDAKZnJhbWVfZGlnIDAKbGVuCnB1c2hpbnQgMzIgLy8gMzIKPT0KYXNzZXJ0CmZyYW1lX2RpZyAwCmJveF9sZW4Kc3RvcmUgNjEKc3RvcmUgNjAKbG9hZCA2MQpmcmFtZV9idXJ5IDAKcmV0c3ViCgovLyBnZXRfcHJlY29uZGl0aW9ucwpnZXRwcmVjb25kaXRpb25zXzExOgpwcm90byAzIDEKYnl0ZWNfMSAvLyAiIgppbnRjXzAgLy8gMApkdXBuIDUKYnl0ZWNfMSAvLyAiIgpkdXAKY2FsbHN1YiB2b3RpbmdvcGVuXzkKZnJhbWVfYnVyeSAxCmZyYW1lX2RpZyAtMwpleHRyYWN0IDIgMApmcmFtZV9kaWcgLTIKZnJhbWVfZGlnIC0xCmNhbGxzdWIgYWxsb3dlZHRvdm90ZV84CmZyYW1lX2J1cnkgMgpjYWxsc3ViIGFscmVhZHl2b3RlZF8xMApmcmFtZV9idXJ5IDMKZ2xvYmFsIExhdGVzdFRpbWVzdGFtcApmcmFtZV9idXJ5IDQKZnJhbWVfZGlnIDEKaXRvYgpmcmFtZV9kaWcgMgppdG9iCmNvbmNhdApmcmFtZV9kaWcgMwppdG9iCmNvbmNhdApmcmFtZV9kaWcgNAppdG9iCmNvbmNhdApmcmFtZV9idXJ5IDAKcmV0c3ViCgovLyB2b3RlCnZvdGVfMTI6CnByb3RvIDYgMApieXRlY18xIC8vICIiCmludGNfMCAvLyAwCmR1cG4gMTEKYnl0ZWNfMSAvLyAiIgpmcmFtZV9kaWcgLTEKdHhuYXMgQXBwbGljYXRpb25zCmJ5dGVjXzIgLy8gIm91YWlkIgphcHBfZ2xvYmFsX2dldAo9PQovLyBPcFVwIGFwcCBJRCBub3QgcGFzc2VkIGluCmFzc2VydApmcmFtZV9kaWcgLTUKZXh0cmFjdCAyIDAKZnJhbWVfZGlnIC00CmZyYW1lX2RpZyAtMQpjYWxsc3ViIGFsbG93ZWR0b3ZvdGVfOAovLyBOb3QgYWxsb3dlZCB0byB2b3RlCmFzc2VydApjYWxsc3ViIHZvdGluZ29wZW5fOQovLyBWb3Rpbmcgbm90IG9wZW4KYXNzZXJ0CmNhbGxzdWIgYWxyZWFkeXZvdGVkXzEwCiEKLy8gQWxyZWFkeSB2b3RlZAphc3NlcnQKYnl0ZWMgNCAvLyAib3B0aW9uX2NvdW50cyIKYXBwX2dsb2JhbF9nZXQKZnJhbWVfYnVyeSAwCmZyYW1lX2RpZyAwCmludGNfMCAvLyAwCmV4dHJhY3RfdWludDE2CmZyYW1lX2J1cnkgMQpmcmFtZV9kaWcgMQpzdG9yZSA2MgpmcmFtZV9kaWcgLTMKaW50Y18wIC8vIDAKZXh0cmFjdF91aW50MTYKZnJhbWVfYnVyeSAyCmZyYW1lX2RpZyAyCmxvYWQgNjIKPT0KLy8gTnVtYmVyIG9mIGFuc3dlcnMgaW5jb3JyZWN0CmFzc2VydApieXRlY18wIC8vICJ2b3RlX3R5cGUiCmFwcF9nbG9iYWxfZ2V0CmludGNfMyAvLyAzCj09CmJueiB2b3RlXzEyX2wyMApmcmFtZV9kaWcgLTIKaW50Y18wIC8vIDAKZXh0cmFjdF91aW50MTYKZnJhbWVfYnVyeSA0CmZyYW1lX2RpZyA0CmludGNfMCAvLyAwCj09Ci8vIE51bWJlciBvZiBhbnN3ZXIgd2VpZ2h0cyBzaG91bGQgYmUgMCBzaW5jZSB0aGlzIHZvdGUgZG9lc24ndCB1c2UgcGFydGl0aW9uZWQgd2VpZ2h0aW5nCmFzc2VydAp2b3RlXzEyX2wyOgpwdXNoaW50IDI1MDAgLy8gMjUwMApwdXNoaW50IDM0IC8vIDM0CmludGNfMSAvLyAxCmZyYW1lX2RpZyAtMwppbnRjXzAgLy8gMApleHRyYWN0X3VpbnQxNgpmcmFtZV9idXJ5IDYKZnJhbWVfZGlnIDYKKgorCnB1c2hpbnQgNDAwIC8vIDQwMAoqCisKc3RvcmUgNjMKZnJhbWVfZGlnIC02Cmd0eG5zIFJlY2VpdmVyCmdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCj09Ci8vIFBheW1lbnQgbXVzdCBiZSB0byBhcHAgYWRkcmVzcwphc3NlcnQKbG9hZCA2MwppdG9iCmxvZwpmcmFtZV9kaWcgLTYKZ3R4bnMgQW1vdW50CmxvYWQgNjMKPT0KLy8gUGF5bWVudCBtdXN0IGJlIHRoZSBleGFjdCBtaW4gYmFsYW5jZSByZXF1aXJlbWVudAphc3NlcnQKaW50Y18wIC8vIDAKc3RvcmUgNjQKaW50Y18wIC8vIDAKc3RvcmUgNjUKaW50Y18wIC8vIDAKc3RvcmUgNjYKdm90ZV8xMl9sMzoKbG9hZCA2Ngpsb2FkIDYyCjwKYm56IHZvdGVfMTJfbDYKYnl0ZWNfMCAvLyAidm90ZV90eXBlIgphcHBfZ2xvYmFsX2dldAppbnRjXzMgLy8gMwo9PQpieiB2b3RlXzEyX2wyMQpsb2FkIDY1CmZyYW1lX2RpZyAtNAo9PQovLyBEaWRuJ3QgcGFydGl0aW9uIGV4YWN0IHZvdGluZyB3ZWlnaHQgYWNyb3NzIHF1ZXN0aW9ucwphc3NlcnQKYiB2b3RlXzEyX2wyMQp2b3RlXzEyX2w2OgpnbG9iYWwgT3Bjb2RlQnVkZ2V0CnB1c2hpbnQgMTAwIC8vIDEwMAo8CmJueiB2b3RlXzEyX2wxNwp2b3RlXzEyX2w3OgpmcmFtZV9kaWcgLTMKaW50Y18xIC8vIDEKbG9hZCA2NgoqCnB1c2hpbnQgMiAvLyAyCisKZ2V0Ynl0ZQpmcmFtZV9idXJ5IDcKaW50Y18wIC8vIDAKZnJhbWVfYnVyeSA5CmJ5dGVjXzAgLy8gInZvdGVfdHlwZSIKYXBwX2dsb2JhbF9nZXQKaW50Y18zIC8vIDMKPT0KYm56IHZvdGVfMTJfbDE2CnZvdGVfMTJfbDg6CmZyYW1lX2RpZyAwCmludGNfMSAvLyAxCmxvYWQgNjYKKgpwdXNoaW50IDIgLy8gMgorCmdldGJ5dGUKZnJhbWVfYnVyeSAxMQpmcmFtZV9kaWcgNwpmcmFtZV9kaWcgMTEKPAovLyBBbnN3ZXIgb3B0aW9uIGluZGV4IGludmFsaWQKYXNzZXJ0CnB1c2hpbnQgOCAvLyA4CmxvYWQgNjQKZnJhbWVfZGlnIDcKKwoqCnN0b3JlIDY4CmJ5dGVjIDkgLy8gIlYiCmxvYWQgNjgKcHVzaGludCA4IC8vIDgKYm94X2V4dHJhY3QKYnRvaQpzdG9yZSA2OQpieXRlYyA5IC8vICJWIgpsb2FkIDY4CmxvYWQgNjkKYnl0ZWNfMCAvLyAidm90ZV90eXBlIgphcHBfZ2xvYmFsX2dldAppbnRjXzAgLy8gMAo9PQpieXRlY18wIC8vICJ2b3RlX3R5cGUiCmFwcF9nbG9iYWxfZ2V0CmludGNfMSAvLyAxCj09Cnx8CmJueiB2b3RlXzEyX2wxNQpieXRlY18wIC8vICJ2b3RlX3R5cGUiCmFwcF9nbG9iYWxfZ2V0CnB1c2hpbnQgMiAvLyAyCj09CmJueiB2b3RlXzEyX2wxNApmcmFtZV9kaWcgOQp2b3RlXzEyX2wxMToKKwppdG9iCmJveF9yZXBsYWNlCmxvYWQgNjQKZnJhbWVfZGlnIDExCisKc3RvcmUgNjQKYnl0ZWNfMCAvLyAidm90ZV90eXBlIgphcHBfZ2xvYmFsX2dldAppbnRjXzMgLy8gMwo9PQpibnogdm90ZV8xMl9sMTMKdm90ZV8xMl9sMTI6CmxvYWQgNjYKaW50Y18xIC8vIDEKKwpzdG9yZSA2NgpiIHZvdGVfMTJfbDMKdm90ZV8xMl9sMTM6CmxvYWQgNjUKZnJhbWVfZGlnIDkKKwpzdG9yZSA2NQpiIHZvdGVfMTJfbDEyCnZvdGVfMTJfbDE0OgpmcmFtZV9kaWcgLTQKYiB2b3RlXzEyX2wxMQp2b3RlXzEyX2wxNToKaW50Y18xIC8vIDEKYiB2b3RlXzEyX2wxMQp2b3RlXzEyX2wxNjoKZnJhbWVfZGlnIC0yCnB1c2hpbnQgOCAvLyA4CmxvYWQgNjYKKgpwdXNoaW50IDIgLy8gMgorCmV4dHJhY3RfdWludDY0CmZyYW1lX2J1cnkgOQpiIHZvdGVfMTJfbDgKdm90ZV8xMl9sMTc6CnB1c2hpbnQgNjgwIC8vIDY4MAppbnRjXzIgLy8gMTAKKwpzdG9yZSA2Nwp2b3RlXzEyX2wxODoKbG9hZCA2NwpnbG9iYWwgT3Bjb2RlQnVkZ2V0Cj4KYnogdm90ZV8xMl9sNwppdHhuX2JlZ2luCnB1c2hpbnQgNiAvLyBhcHBsCml0eG5fZmllbGQgVHlwZUVudW0KYnl0ZWNfMiAvLyAib3VhaWQiCmFwcF9nbG9iYWxfZ2V0Cml0eG5fZmllbGQgQXBwbGljYXRpb25JRApieXRlYyAxNiAvLyAib3B1cCgpdm9pZCIKaXR4bl9maWVsZCBBcHBsaWNhdGlvbkFyZ3MKaW50Y18wIC8vIDAKaXR4bl9maWVsZCBGZWUKaXR4bl9zdWJtaXQKYiB2b3RlXzEyX2wxOAp2b3RlXzEyX2wyMDoKZnJhbWVfZGlnIC0yCmludGNfMCAvLyAwCmV4dHJhY3RfdWludDE2CmZyYW1lX2J1cnkgMwpmcmFtZV9kaWcgMwpsb2FkIDYyCj09Ci8vIE51bWJlciBvZiBhbnN3ZXIgd2VpZ2h0cyBpbmNvcnJlY3QsIHNob3VsZCBtYXRjaCBudW1iZXIgb2YgcXVlc3Rpb25zIHNpbmNlIHRoaXMgdm90ZSB1c2VzIHBhcnRpdGlvbmVkIHdlaWdodGluZwphc3NlcnQKYiB2b3RlXzEyX2wyCnZvdGVfMTJfbDIxOgp0eG4gU2VuZGVyCmZyYW1lX2J1cnkgMTMKZnJhbWVfZGlnIDEzCmxlbgpwdXNoaW50IDMyIC8vIDMyCj09CmFzc2VydApmcmFtZV9kaWcgMTMKYm94X2RlbApwb3AKZnJhbWVfZGlnIDEzCmZyYW1lX2RpZyAtMwpib3hfcHV0CmJ5dGVjIDYgLy8gInZvdGVyX2NvdW50IgpieXRlYyA2IC8vICJ2b3Rlcl9jb3VudCIKYXBwX2dsb2JhbF9nZXQKaW50Y18xIC8vIDEKKwphcHBfZ2xvYmFsX3B1dApyZXRzdWI=', - clear: 'I3ByYWdtYSB2ZXJzaW9uIDgKcHVzaGludCAwIC8vIDAKcmV0dXJu', - }, - state: { - global: { - num_byte_slices: 5, - num_uints: 10, - }, - local: { - num_byte_slices: 0, - num_uints: 0, - }, - }, - schema: { - global: { - declared: { - close_time: { - type: 'uint64', - key: 'close_time', - descr: 'The unix timestamp of the time the vote was closed', - }, - end_time: { - type: 'uint64', - key: 'end_time', - descr: 'The unix timestamp of the ending time of voting', - }, - is_bootstrapped: { - type: 'uint64', - key: 'is_bootstrapped', - descr: 'Whether or not the contract has been bootstrapped with answers', - }, - metadata_ipfs_cid: { - type: 'bytes', - key: 'metadata_ipfs_cid', - descr: 'The IPFS content ID of the voting metadata file', - }, - nft_asset_id: { - type: 'uint64', - key: 'nft_asset_id', - descr: 'The asset ID of a result NFT if one has been created', - }, - nft_image_url: { - type: 'bytes', - key: 'nft_image_url', - descr: 'The IPFS URL of the default image to use as the media of the result NFT', - }, - option_counts: { - type: 'bytes', - key: 'option_counts', - descr: 'The number of options for each question', - }, - opup_app_id: { - type: 'uint64', - key: 'ouaid', - descr: '', - }, - quorum: { - type: 'uint64', - key: 'quorum', - descr: 'The minimum number of voters to reach quorum', - }, - snapshot_public_key: { - type: 'bytes', - key: 'snapshot_public_key', - descr: 'The public key of the Ed25519 compatible private key that was used to encrypt entries in the vote gating snapshot', - }, - start_time: { - type: 'uint64', - key: 'start_time', - descr: 'The unix timestamp of the starting time of voting', - }, - total_options: { - type: 'uint64', - key: 'total_options', - descr: 'The total number of options', - }, - vote_id: { - type: 'bytes', - key: 'vote_id', - descr: 'The identifier of this voting round', - }, - vote_type: { - type: 'uint64', - key: 'vote_type', - descr: - 'The type of this voting round; 0 = no snapshot / weighting, 1 = snapshot & no weighting, 2 = snapshot & weighting per question, 3 = snapshot & weighting partitioned across the questions', - }, - voter_count: { - type: 'uint64', - key: 'voter_count', - descr: 'The minimum number of voters who have voted', - }, - }, - reserved: {}, - }, - local: { - declared: {}, - reserved: {}, - }, - }, - contract: { - name: 'VotingRoundApp', - methods: [ - { - name: 'opup_bootstrap', - args: [ - { - type: 'pay', - name: 'ptxn', - }, - ], - returns: { - type: 'uint64', - }, - desc: 'initialize opup with bootstrap to create a target app', - }, - { - name: 'create', - args: [ - { - type: 'string', - name: 'vote_id', - }, - { - type: 'uint8', - name: 'vote_type', - }, - { - type: 'byte[]', - name: 'snapshot_public_key', - }, - { - type: 'string', - name: 'metadata_ipfs_cid', - }, - { - type: 'uint64', - name: 'start_time', - }, - { - type: 'uint64', - name: 'end_time', - }, - { - type: 'uint8[]', - name: 'option_counts', - }, - { - type: 'uint64', - name: 'quorum', - }, - { - type: 'string', - name: 'nft_image_url', - }, - ], - returns: { - type: 'void', - }, - }, - { - name: 'bootstrap', - args: [ - { - type: 'pay', - name: 'fund_min_bal_req', - }, - ], - returns: { - type: 'void', - }, - }, - { - name: 'close', - args: [ - { - type: 'application', - name: 'opup_app', - }, - ], - returns: { - type: 'void', - }, - }, - { - name: 'get_preconditions', - args: [ - { - type: 'byte[]', - name: 'signature', - }, - { - type: 'uint64', - name: 'weighting', - }, - { - type: 'application', - name: 'opup_app', - }, - ], - returns: { - type: '(uint64,uint64,uint64,uint64)', - }, - }, - { - name: 'vote', - args: [ - { - type: 'pay', - name: 'fund_min_bal_req', - }, - { - type: 'byte[]', - name: 'signature', - }, - { - type: 'uint64', - name: 'weighting', - }, - { - type: 'uint8[]', - name: 'answer_ids', - }, - { - type: 'uint64[]', - name: 'answer_weights', - }, - { - type: 'application', - name: 'opup_app', - }, - ], - returns: { - type: 'void', - }, - }, - ], - networks: {}, - }, - bare_call_config: { - delete_application: 'CALL', - }, -} +import { AppFactory as _AppFactory, AppFactoryAppClientParams, AppFactoryResolveAppClientByCreatorAndNameParams, AppFactoryDeployParams, AppFactoryParams, CreateSchema } from '@algorandfoundation/algokit-utils/types/app-factory' +import { TransactionComposer, AppCallMethodCall, AppMethodCallTransactionArgument, SimulateOptions } from '@algorandfoundation/algokit-utils/types/composer' +import { SendParams, SendSingleTransactionResult, SendAtomicTransactionComposerResults } from '@algorandfoundation/algokit-utils/types/transaction' +import { Address, encodeAddress, modelsv2, OnApplicationComplete, Transaction, TransactionSigner } from 'algosdk' +import SimulateResponse = modelsv2.SimulateResponse + +export const APP_SPEC: Arc56Contract = {"arcs":[],"name":"VotingRoundApp","structs":{"VotingPreconditions":[{"name":"isVotingOpen","type":"uint64"},{"name":"isAllowedToVote","type":"uint64"},{"name":"hasAlreadyVoted","type":"uint64"},{"name":"currentTime","type":"uint64"}]},"methods":[{"name":"opup_bootstrap","desc":"initialize opup with bootstrap to create a target app","args":[{"name":"ptxn","type":"pay"}],"returns":{"type":"uint64"},"events":[],"actions":{"create":[],"call":["NoOp"]}},{"name":"create","args":[{"name":"vote_id","type":"string"},{"name":"vote_type","type":"uint8"},{"name":"snapshot_public_key","type":"byte[]"},{"name":"metadata_ipfs_cid","type":"string"},{"name":"start_time","type":"uint64"},{"name":"end_time","type":"uint64"},{"name":"option_counts","type":"uint8[]"},{"name":"quorum","type":"uint64"},{"name":"nft_image_url","type":"string"}],"returns":{"type":"void"},"events":[],"actions":{"create":["NoOp"],"call":[]}},{"name":"bootstrap","args":[{"name":"fund_min_bal_req","type":"pay"}],"returns":{"type":"void"},"events":[],"actions":{"create":[],"call":["NoOp"]}},{"name":"close","args":[{"name":"opup_app","type":"application","defaultValue":{"source":"global","data":"b3VhaWQ=","type":"application"}}],"returns":{"type":"void"},"events":[],"actions":{"create":[],"call":["NoOp"]}},{"name":"get_preconditions","args":[{"name":"signature","type":"byte[]"},{"name":"weighting","type":"uint64"},{"name":"opup_app","type":"application","defaultValue":{"source":"global","data":"b3VhaWQ=","type":"application"}}],"returns":{"type":"(uint64,uint64,uint64,uint64)","struct":"VotingPreconditions"},"events":[],"readonly":true,"actions":{"create":[],"call":["NoOp"]}},{"name":"vote","args":[{"name":"fund_min_bal_req","type":"pay"},{"name":"signature","type":"byte[]"},{"name":"weighting","type":"uint64"},{"name":"answer_ids","type":"uint8[]"},{"name":"answer_weights","type":"uint64[]"},{"name":"opup_app","type":"application","defaultValue":{"source":"global","data":"b3VhaWQ=","type":"application"}}],"returns":{"type":"void"},"events":[],"actions":{"create":[],"call":["NoOp"]}}],"state":{"schema":{"global":{"ints":10,"bytes":5},"local":{"ints":0,"bytes":0}},"keys":{"global":{"close_time":{"key":"Y2xvc2VfdGltZQ==","keyType":"AVMString","valueType":"AVMUint64","desc":"The unix timestamp of the time the vote was closed"},"end_time":{"key":"ZW5kX3RpbWU=","keyType":"AVMString","valueType":"AVMUint64","desc":"The unix timestamp of the ending time of voting"},"is_bootstrapped":{"key":"aXNfYm9vdHN0cmFwcGVk","keyType":"AVMString","valueType":"AVMUint64","desc":"Whether or not the contract has been bootstrapped with answers"},"metadata_ipfs_cid":{"key":"bWV0YWRhdGFfaXBmc19jaWQ=","keyType":"AVMString","valueType":"AVMBytes","desc":"The IPFS content ID of the voting metadata file"},"nft_asset_id":{"key":"bmZ0X2Fzc2V0X2lk","keyType":"AVMString","valueType":"AVMUint64","desc":"The asset ID of a result NFT if one has been created"},"nft_image_url":{"key":"bmZ0X2ltYWdlX3VybA==","keyType":"AVMString","valueType":"AVMBytes","desc":"The IPFS URL of the default image to use as the media of the result NFT"},"option_counts":{"key":"b3B0aW9uX2NvdW50cw==","keyType":"AVMString","valueType":"AVMBytes","desc":"The number of options for each question"},"opup_app_id":{"key":"b3VhaWQ=","keyType":"AVMString","valueType":"AVMUint64","desc":""},"quorum":{"key":"cXVvcnVt","keyType":"AVMString","valueType":"AVMUint64","desc":"The minimum number of voters to reach quorum"},"snapshot_public_key":{"key":"c25hcHNob3RfcHVibGljX2tleQ==","keyType":"AVMString","valueType":"AVMBytes","desc":"The public key of the Ed25519 compatible private key that was used to encrypt entries in the vote gating snapshot"},"start_time":{"key":"c3RhcnRfdGltZQ==","keyType":"AVMString","valueType":"AVMUint64","desc":"The unix timestamp of the starting time of voting"},"total_options":{"key":"dG90YWxfb3B0aW9ucw==","keyType":"AVMString","valueType":"AVMUint64","desc":"The total number of options"},"vote_id":{"key":"dm90ZV9pZA==","keyType":"AVMString","valueType":"AVMBytes","desc":"The identifier of this voting round"},"vote_type":{"key":"dm90ZV90eXBl","keyType":"AVMString","valueType":"AVMUint64","desc":"The type of this voting round; 0 = no snapshot / weighting, 1 = snapshot & no weighting, 2 = snapshot & weighting per question, 3 = snapshot & weighting partitioned across the questions"},"voter_count":{"key":"dm90ZXJfY291bnQ=","keyType":"AVMString","valueType":"AVMUint64","desc":"The minimum number of voters who have voted"}},"local":{},"box":{}},"maps":{"global":{},"local":{},"box":{}}},"source":{"approval":"I3ByYWdtYSB2ZXJzaW9uIDgKaW50Y2Jsb2NrIDAgMSAxMCAzCmJ5dGVjYmxvY2sgMHg3NjZmNzQ2NTVmNzQ3OTcwNjUgMHggMHg2Zjc1NjE2OTY0IDB4NzY2Zjc0NjU1ZjY5NjQgMHg2ZjcwNzQ2OTZmNmU1ZjYzNmY3NTZlNzQ3MyAweDY5NzM1ZjYyNmY2Zjc0NzM3NDcyNjE3MDcwNjU2NCAweDc2NmY3NDY1NzI1ZjYzNmY3NTZlNzQgMHg2MzZjNmY3MzY1NWY3NDY5NmQ2NSAweDc0NmY3NDYxNmM1ZjZmNzA3NDY5NmY2ZTczIDB4NTYgMHg3MzZlNjE3MDczNjg2Zjc0NWY3MDc1NjI2YzY5NjM1ZjZiNjU3OSAweDZkNjU3NDYxNjQ2MTc0NjE1ZjY5NzA2NjczNWY2MzY5NjQgMHg3Mzc0NjE3Mjc0NWY3NDY5NmQ2NSAweDY1NmU2NDVmNzQ2OTZkNjUgMHg3MTc1NmY3Mjc1NmQgMHg2ZTY2NzQ1ZjY5NmQ2MTY3NjU1Zjc1NzI2YyAweDRjNmJlYTcyIDB4MTUxZjdjNzUgMHg2ZTY2NzQ1ZjYxNzM3MzY1NzQ1ZjY5NjQgMHgwNjgxMDEgMHgyYwp0eG4gTnVtQXBwQXJncwppbnRjXzAgLy8gMAo9PQpibnogbWFpbl9sMTQKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMApwdXNoYnl0ZXMgMHgxMDFjZWEwMCAvLyAib3B1cF9ib290c3RyYXAocGF5KXVpbnQ2NCIKPT0KYm56IG1haW5fbDEzCnR4bmEgQXBwbGljYXRpb25BcmdzIDAKcHVzaGJ5dGVzIDB4NWQ0Y2YwNjYgLy8gImNyZWF0ZShzdHJpbmcsdWludDgsYnl0ZVtdLHN0cmluZyx1aW50NjQsdWludDY0LHVpbnQ4W10sdWludDY0LHN0cmluZyl2b2lkIgo9PQpibnogbWFpbl9sMTIKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMApwdXNoYnl0ZXMgMHhhNGU4ZDE2NCAvLyAiYm9vdHN0cmFwKHBheSl2b2lkIgo9PQpibnogbWFpbl9sMTEKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMApwdXNoYnl0ZXMgMHg5NTQ2ZTEwZiAvLyAiY2xvc2UoYXBwbGljYXRpb24pdm9pZCIKPT0KYm56IG1haW5fbDEwCnR4bmEgQXBwbGljYXRpb25BcmdzIDAKcHVzaGJ5dGVzIDB4MzYzMzA4MjQgLy8gImdldF9wcmVjb25kaXRpb25zKGJ5dGVbXSx1aW50NjQsYXBwbGljYXRpb24pKHVpbnQ2NCx1aW50NjQsdWludDY0LHVpbnQ2NCkiCj09CmJueiBtYWluX2w5CnR4bmEgQXBwbGljYXRpb25BcmdzIDAKcHVzaGJ5dGVzIDB4YzQwZmZkYWEgLy8gInZvdGUocGF5LGJ5dGVbXSx1aW50NjQsdWludDhbXSx1aW50NjRbXSxhcHBsaWNhdGlvbil2b2lkIgo9PQpibnogbWFpbl9sOAplcnIKbWFpbl9sODoKdHhuIE9uQ29tcGxldGlvbgppbnRjXzAgLy8gTm9PcAo9PQp0eG4gQXBwbGljYXRpb25JRAppbnRjXzAgLy8gMAohPQomJgphc3NlcnQKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQpzdG9yZSAxNwp0eG5hIEFwcGxpY2F0aW9uQXJncyAyCmJ0b2kKc3RvcmUgMTgKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwpzdG9yZSAxOQp0eG5hIEFwcGxpY2F0aW9uQXJncyA0CnN0b3JlIDIwCnR4bmEgQXBwbGljYXRpb25BcmdzIDUKaW50Y18wIC8vIDAKZ2V0Ynl0ZQpzdG9yZSAyMQp0eG4gR3JvdXBJbmRleAppbnRjXzEgLy8gMQotCnN0b3JlIDE2CmxvYWQgMTYKZ3R4bnMgVHlwZUVudW0KaW50Y18xIC8vIHBheQo9PQphc3NlcnQKbG9hZCAxNgpsb2FkIDE3CmxvYWQgMTgKbG9hZCAxOQpsb2FkIDIwCmxvYWQgMjEKY2FsbHN1YiB2b3RlXzEyCmludGNfMSAvLyAxCnJldHVybgptYWluX2w5Ogp0eG4gT25Db21wbGV0aW9uCmludGNfMCAvLyBOb09wCj09CnR4biBBcHBsaWNhdGlvbklECmludGNfMCAvLyAwCiE9CiYmCmFzc2VydAp0eG5hIEFwcGxpY2F0aW9uQXJncyAxCnN0b3JlIDEyCnR4bmEgQXBwbGljYXRpb25BcmdzIDIKYnRvaQpzdG9yZSAxMwp0eG5hIEFwcGxpY2F0aW9uQXJncyAzCmludGNfMCAvLyAwCmdldGJ5dGUKc3RvcmUgMTQKbG9hZCAxMgpsb2FkIDEzCmxvYWQgMTQKY2FsbHN1YiBnZXRwcmVjb25kaXRpb25zXzExCnN0b3JlIDE1CmJ5dGVjIDE3IC8vIDB4MTUxZjdjNzUKbG9hZCAxNQpjb25jYXQKbG9nCmludGNfMSAvLyAxCnJldHVybgptYWluX2wxMDoKdHhuIE9uQ29tcGxldGlvbgppbnRjXzAgLy8gTm9PcAo9PQp0eG4gQXBwbGljYXRpb25JRAppbnRjXzAgLy8gMAohPQomJgphc3NlcnQKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQppbnRjXzAgLy8gMApnZXRieXRlCmNhbGxzdWIgY2xvc2VfNwppbnRjXzEgLy8gMQpyZXR1cm4KbWFpbl9sMTE6CnR4biBPbkNvbXBsZXRpb24KaW50Y18wIC8vIE5vT3AKPT0KdHhuIEFwcGxpY2F0aW9uSUQKaW50Y18wIC8vIDAKIT0KJiYKYXNzZXJ0CnR4biBHcm91cEluZGV4CmludGNfMSAvLyAxCi0Kc3RvcmUgMTEKbG9hZCAxMQpndHhucyBUeXBlRW51bQppbnRjXzEgLy8gcGF5Cj09CmFzc2VydApsb2FkIDExCmNhbGxzdWIgYm9vdHN0cmFwXzYKaW50Y18xIC8vIDEKcmV0dXJuCm1haW5fbDEyOgp0eG4gT25Db21wbGV0aW9uCmludGNfMCAvLyBOb09wCj09CnR4biBBcHBsaWNhdGlvbklECmludGNfMCAvLyAwCj09CiYmCmFzc2VydAp0eG5hIEFwcGxpY2F0aW9uQXJncyAxCnN0b3JlIDIKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgppbnRjXzAgLy8gMApnZXRieXRlCnN0b3JlIDMKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwpzdG9yZSA0CnR4bmEgQXBwbGljYXRpb25BcmdzIDQKc3RvcmUgNQp0eG5hIEFwcGxpY2F0aW9uQXJncyA1CmJ0b2kKc3RvcmUgNgp0eG5hIEFwcGxpY2F0aW9uQXJncyA2CmJ0b2kKc3RvcmUgNwp0eG5hIEFwcGxpY2F0aW9uQXJncyA3CnN0b3JlIDgKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgOApidG9pCnN0b3JlIDkKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgOQpzdG9yZSAxMApsb2FkIDIKbG9hZCAzCmxvYWQgNApsb2FkIDUKbG9hZCA2CmxvYWQgNwpsb2FkIDgKbG9hZCA5CmxvYWQgMTAKY2FsbHN1YiBjcmVhdGVfNQppbnRjXzEgLy8gMQpyZXR1cm4KbWFpbl9sMTM6CnR4biBPbkNvbXBsZXRpb24KaW50Y18wIC8vIE5vT3AKPT0KdHhuIEFwcGxpY2F0aW9uSUQKaW50Y18wIC8vIDAKIT0KJiYKYXNzZXJ0CnR4biBHcm91cEluZGV4CmludGNfMSAvLyAxCi0Kc3RvcmUgMApsb2FkIDAKZ3R4bnMgVHlwZUVudW0KaW50Y18xIC8vIHBheQo9PQphc3NlcnQKbG9hZCAwCmNhbGxzdWIgb3B1cGJvb3RzdHJhcF8zCnN0b3JlIDEKYnl0ZWMgMTcgLy8gMHgxNTFmN2M3NQpsb2FkIDEKaXRvYgpjb25jYXQKbG9nCmludGNfMSAvLyAxCnJldHVybgptYWluX2wxNDoKdHhuIE9uQ29tcGxldGlvbgpwdXNoaW50IDUgLy8gRGVsZXRlQXBwbGljYXRpb24KPT0KYm56IG1haW5fbDE2CmVycgptYWluX2wxNjoKdHhuIEFwcGxpY2F0aW9uSUQKaW50Y18wIC8vIDAKIT0KYXNzZXJ0CmNhbGxzdWIgZGVsZXRlXzIKaW50Y18xIC8vIDEKcmV0dXJuCgovLyBpbnRfdG9fYXNjaWkKaW50dG9hc2NpaV8wOgpwcm90byAxIDEKcHVzaGJ5dGVzIDB4MzAzMTMyMzMzNDM1MzYzNzM4MzkgLy8gIjAxMjM0NTY3ODkiCmZyYW1lX2RpZyAtMQppbnRjXzEgLy8gMQpleHRyYWN0MwpyZXRzdWIKCi8vIGl0b2EKaXRvYV8xOgpwcm90byAxIDEKZnJhbWVfZGlnIC0xCmludGNfMCAvLyAwCj09CmJueiBpdG9hXzFfbDUKZnJhbWVfZGlnIC0xCmludGNfMiAvLyAxMAovCmludGNfMCAvLyAwCj4KYm56IGl0b2FfMV9sNApieXRlY18xIC8vICIiCml0b2FfMV9sMzoKZnJhbWVfZGlnIC0xCmludGNfMiAvLyAxMAolCmNhbGxzdWIgaW50dG9hc2NpaV8wCmNvbmNhdApiIGl0b2FfMV9sNgppdG9hXzFfbDQ6CmZyYW1lX2RpZyAtMQppbnRjXzIgLy8gMTAKLwpjYWxsc3ViIGl0b2FfMQpiIGl0b2FfMV9sMwppdG9hXzFfbDU6CnB1c2hieXRlcyAweDMwIC8vICIwIgppdG9hXzFfbDY6CnJldHN1YgoKLy8gZGVsZXRlCmRlbGV0ZV8yOgpwcm90byAwIDAKdHhuIFNlbmRlcgpnbG9iYWwgQ3JlYXRvckFkZHJlc3MKPT0KLy8gdW5hdXRob3JpemVkCmFzc2VydApwdXNoaW50IFRNUExfREVMRVRBQkxFIC8vIFRNUExfREVMRVRBQkxFCi8vIENoZWNrIGFwcCBpcyBkZWxldGFibGUKYXNzZXJ0CnJldHN1YgoKLy8gb3B1cF9ib290c3RyYXAKb3B1cGJvb3RzdHJhcF8zOgpwcm90byAxIDEKaW50Y18wIC8vIDAKZnJhbWVfZGlnIC0xCmd0eG5zIEFtb3VudApwdXNoaW50IDEwMDAwMCAvLyAxMDAwMDAKPj0KYXNzZXJ0CmNhbGxzdWIgY3JlYXRlb3B1cF80CmJ5dGVjXzIgLy8gIm91YWlkIgphcHBfZ2xvYmFsX2dldApmcmFtZV9idXJ5IDAKcmV0c3ViCgovLyBjcmVhdGVfb3B1cApjcmVhdGVvcHVwXzQ6CnByb3RvIDAgMAppdHhuX2JlZ2luCnB1c2hpbnQgNiAvLyBhcHBsCml0eG5fZmllbGQgVHlwZUVudW0KcHVzaGJ5dGVzIDB4MDgyMDAyMDAwMTMxMWIyMjEyNDAwMDFkMzYxYTAwODAwNDRjNmJlYTcyMTI0MDAwMDEwMDMxMTkyMjEyMzExODIyMTMxMDQ0ODgwMDExMjM0MzMxMTkyMjEyNDAwMDAxMDAzMTE4MjIxMjQ0MjM0MzhhMDAwMDMxMDAzMjA5MTI0NDIzNDMgLy8gMHgwODIwMDIwMDAxMzExYjIyMTI0MDAwMWQzNjFhMDA4MDA0NGM2YmVhNzIxMjQwMDAwMTAwMzExOTIyMTIzMTE4MjIxMzEwNDQ4ODAwMTEyMzQzMzExOTIyMTI0MDAwMDEwMDMxMTgyMjEyNDQyMzQzOGEwMDAwMzEwMDMyMDkxMjQ0MjM0MwppdHhuX2ZpZWxkIEFwcHJvdmFsUHJvZ3JhbQpwdXNoYnl0ZXMgMHgwODgxMDA0MyAvLyAweDA4ODEwMDQzCml0eG5fZmllbGQgQ2xlYXJTdGF0ZVByb2dyYW0KaW50Y18wIC8vIDAKaXR4bl9maWVsZCBGZWUKaXR4bl9zdWJtaXQKaW50Y18wIC8vIDAKYnl0ZWNfMiAvLyAib3VhaWQiCmFwcF9nbG9iYWxfZ2V0X2V4CnN0b3JlIDIzCnN0b3JlIDIyCmxvYWQgMjMKIQphc3NlcnQKYnl0ZWNfMiAvLyAib3VhaWQiCml0eG4gQ3JlYXRlZEFwcGxpY2F0aW9uSUQKYXBwX2dsb2JhbF9wdXQKcmV0c3ViCgovLyBjcmVhdGUKY3JlYXRlXzU6CnByb3RvIDkgMAppbnRjXzAgLy8gMApkdXAKYnl0ZWNfMSAvLyAiIgppbnRjXzAgLy8gMApkdXBuIDIKZnJhbWVfZGlnIC01CmZyYW1lX2RpZyAtNAo8PQovLyBFbmQgdGltZSBzaG91bGQgYmUgYWZ0ZXIgc3RhcnQgdGltZQphc3NlcnQKZnJhbWVfZGlnIC00Cmdsb2JhbCBMYXRlc3RUaW1lc3RhbXAKPj0KLy8gRW5kIHRpbWUgc2hvdWxkIGJlIGluIHRoZSBmdXR1cmUKYXNzZXJ0CmZyYW1lX2RpZyAtOAppbnRjXzMgLy8gMwo8PQovLyBWb3RlIHR5cGUgc2hvdWxkIGJlIDw9IDMKYXNzZXJ0CmludGNfMCAvLyAwCmJ5dGVjXzMgLy8gInZvdGVfaWQiCmFwcF9nbG9iYWxfZ2V0X2V4CnN0b3JlIDI1CnN0b3JlIDI0CmxvYWQgMjUKIQphc3NlcnQKYnl0ZWNfMyAvLyAidm90ZV9pZCIKZnJhbWVfZGlnIC05CmV4dHJhY3QgMiAwCmFwcF9nbG9iYWxfcHV0CmludGNfMCAvLyAwCmJ5dGVjXzAgLy8gInZvdGVfdHlwZSIKYXBwX2dsb2JhbF9nZXRfZXgKc3RvcmUgMjcKc3RvcmUgMjYKbG9hZCAyNwohCmFzc2VydApieXRlY18wIC8vICJ2b3RlX3R5cGUiCmZyYW1lX2RpZyAtOAphcHBfZ2xvYmFsX3B1dAppbnRjXzAgLy8gMApieXRlYyAxMCAvLyAic25hcHNob3RfcHVibGljX2tleSIKYXBwX2dsb2JhbF9nZXRfZXgKc3RvcmUgMjkKc3RvcmUgMjgKbG9hZCAyOQohCmFzc2VydApieXRlYyAxMCAvLyAic25hcHNob3RfcHVibGljX2tleSIKZnJhbWVfZGlnIC03CmV4dHJhY3QgMiAwCmFwcF9nbG9iYWxfcHV0CmludGNfMCAvLyAwCmJ5dGVjIDExIC8vICJtZXRhZGF0YV9pcGZzX2NpZCIKYXBwX2dsb2JhbF9nZXRfZXgKc3RvcmUgMzEKc3RvcmUgMzAKbG9hZCAzMQohCmFzc2VydApieXRlYyAxMSAvLyAibWV0YWRhdGFfaXBmc19jaWQiCmZyYW1lX2RpZyAtNgpleHRyYWN0IDIgMAphcHBfZ2xvYmFsX3B1dAppbnRjXzAgLy8gMApieXRlYyAxMiAvLyAic3RhcnRfdGltZSIKYXBwX2dsb2JhbF9nZXRfZXgKc3RvcmUgMzMKc3RvcmUgMzIKbG9hZCAzMwohCmFzc2VydApieXRlYyAxMiAvLyAic3RhcnRfdGltZSIKZnJhbWVfZGlnIC01CmFwcF9nbG9iYWxfcHV0CmludGNfMCAvLyAwCmJ5dGVjIDEzIC8vICJlbmRfdGltZSIKYXBwX2dsb2JhbF9nZXRfZXgKc3RvcmUgMzUKc3RvcmUgMzQKbG9hZCAzNQohCmFzc2VydApieXRlYyAxMyAvLyAiZW5kX3RpbWUiCmZyYW1lX2RpZyAtNAphcHBfZ2xvYmFsX3B1dAppbnRjXzAgLy8gMApieXRlYyAxNCAvLyAicXVvcnVtIgphcHBfZ2xvYmFsX2dldF9leApzdG9yZSAzNwpzdG9yZSAzNgpsb2FkIDM3CiEKYXNzZXJ0CmJ5dGVjIDE0IC8vICJxdW9ydW0iCmZyYW1lX2RpZyAtMgphcHBfZ2xvYmFsX3B1dApieXRlYyA1IC8vICJpc19ib290c3RyYXBwZWQiCmludGNfMCAvLyAwCmFwcF9nbG9iYWxfcHV0CmJ5dGVjIDYgLy8gInZvdGVyX2NvdW50IgppbnRjXzAgLy8gMAphcHBfZ2xvYmFsX3B1dApieXRlYyA3IC8vICJjbG9zZV90aW1lIgppbnRjXzAgLy8gMAphcHBfZ2xvYmFsX3B1dAppbnRjXzAgLy8gMApieXRlYyAxNSAvLyAibmZ0X2ltYWdlX3VybCIKYXBwX2dsb2JhbF9nZXRfZXgKc3RvcmUgMzkKc3RvcmUgMzgKbG9hZCAzOQohCmFzc2VydApieXRlYyAxNSAvLyAibmZ0X2ltYWdlX3VybCIKZnJhbWVfZGlnIC0xCmV4dHJhY3QgMiAwCmFwcF9nbG9iYWxfcHV0CmJ5dGVjIDE4IC8vICJuZnRfYXNzZXRfaWQiCmludGNfMCAvLyAwCmFwcF9nbG9iYWxfcHV0CmZyYW1lX2RpZyAtMwppbnRjXzAgLy8gMApleHRyYWN0X3VpbnQxNgpmcmFtZV9idXJ5IDAKZnJhbWVfZGlnIDAKLy8gb3B0aW9uX2NvdW50cyBzaG91bGQgYmUgbm9uLWVtcHR5CmFzc2VydApmcmFtZV9kaWcgLTMKaW50Y18wIC8vIDAKZXh0cmFjdF91aW50MTYKZnJhbWVfYnVyeSAxCmZyYW1lX2RpZyAxCnB1c2hpbnQgMTEyIC8vIDExMgo8PQovLyBDYW4ndCBoYXZlIG1vcmUgdGhhbiAxMTIgcXVlc3Rpb25zCmFzc2VydAppbnRjXzAgLy8gMApieXRlYyA0IC8vICJvcHRpb25fY291bnRzIgphcHBfZ2xvYmFsX2dldF9leApzdG9yZSA0MQpzdG9yZSA0MApsb2FkIDQxCiEKYXNzZXJ0CmJ5dGVjIDQgLy8gIm9wdGlvbl9jb3VudHMiCmZyYW1lX2RpZyAtMwphcHBfZ2xvYmFsX3B1dApieXRlYyA0IC8vICJvcHRpb25fY291bnRzIgphcHBfZ2xvYmFsX2dldApmcmFtZV9idXJ5IDIKaW50Y18wIC8vIDAKc3RvcmUgNDMKZnJhbWVfZGlnIDIKaW50Y18wIC8vIDAKZXh0cmFjdF91aW50MTYKZnJhbWVfYnVyeSAzCmZyYW1lX2RpZyAzCnN0b3JlIDQ0CmludGNfMCAvLyAwCnN0b3JlIDQ1CmNyZWF0ZV81X2wxOgpsb2FkIDQ1CmxvYWQgNDQKPApieiBjcmVhdGVfNV9sNwpnbG9iYWwgT3Bjb2RlQnVkZ2V0CnB1c2hpbnQgMTAwIC8vIDEwMAo8CmJueiBjcmVhdGVfNV9sNApjcmVhdGVfNV9sMzoKZnJhbWVfZGlnIDIKaW50Y18xIC8vIDEKbG9hZCA0NQoqCnB1c2hpbnQgMiAvLyAyCisKZ2V0Ynl0ZQpmcmFtZV9idXJ5IDQKbG9hZCA0MwpmcmFtZV9kaWcgNAorCnN0b3JlIDQzCmxvYWQgNDUKaW50Y18xIC8vIDEKKwpzdG9yZSA0NQpiIGNyZWF0ZV81X2wxCmNyZWF0ZV81X2w0OgpwdXNoaW50IDYwMCAvLyA2MDAKaW50Y18yIC8vIDEwCisKc3RvcmUgNDYKY3JlYXRlXzVfbDU6CmxvYWQgNDYKZ2xvYmFsIE9wY29kZUJ1ZGdldAo+CmJ6IGNyZWF0ZV81X2wzCml0eG5fYmVnaW4KcHVzaGludCA2IC8vIGFwcGwKaXR4bl9maWVsZCBUeXBlRW51bQppbnRjXzAgLy8gMAppdHhuX2ZpZWxkIEZlZQpwdXNoaW50IDUgLy8gRGVsZXRlQXBwbGljYXRpb24KaXR4bl9maWVsZCBPbkNvbXBsZXRpb24KYnl0ZWMgMTkgLy8gMHgwNjgxMDEKaXR4bl9maWVsZCBBcHByb3ZhbFByb2dyYW0KYnl0ZWMgMTkgLy8gMHgwNjgxMDEKaXR4bl9maWVsZCBDbGVhclN0YXRlUHJvZ3JhbQppdHhuX3N1Ym1pdApiIGNyZWF0ZV81X2w1CmNyZWF0ZV81X2w3Ogpsb2FkIDQzCnN0b3JlIDQyCmxvYWQgNDIKcHVzaGludCAxMjggLy8gMTI4Cjw9Ci8vIENhbid0IGhhdmUgbW9yZSB0aGFuIDEyOCB2b3RlIG9wdGlvbnMKYXNzZXJ0CmludGNfMCAvLyAwCmJ5dGVjIDggLy8gInRvdGFsX29wdGlvbnMiCmFwcF9nbG9iYWxfZ2V0X2V4CnN0b3JlIDQ4CnN0b3JlIDQ3CmxvYWQgNDgKIQphc3NlcnQKYnl0ZWMgOCAvLyAidG90YWxfb3B0aW9ucyIKbG9hZCA0MgphcHBfZ2xvYmFsX3B1dApyZXRzdWIKCi8vIGJvb3RzdHJhcApib290c3RyYXBfNjoKcHJvdG8gMSAwCmludGNfMCAvLyAwCnR4biBTZW5kZXIKZ2xvYmFsIENyZWF0b3JBZGRyZXNzCj09Ci8vIHVuYXV0aG9yaXplZAphc3NlcnQKYnl0ZWMgNSAvLyAiaXNfYm9vdHN0cmFwcGVkIgphcHBfZ2xvYmFsX2dldAohCi8vIEFscmVhZHkgYm9vdHN0cmFwcGVkCmFzc2VydApieXRlYyA1IC8vICJpc19ib290c3RyYXBwZWQiCmludGNfMSAvLyAxCmFwcF9nbG9iYWxfcHV0CnB1c2hpbnQgMzAzOTAwIC8vIDMwMzkwMApieXRlYyA4IC8vICJ0b3RhbF9vcHRpb25zIgphcHBfZ2xvYmFsX2dldApwdXNoaW50IDMyMDAgLy8gMzIwMAoqCisKc3RvcmUgNDkKZnJhbWVfZGlnIC0xCmd0eG5zIFJlY2VpdmVyCmdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCj09Ci8vIFBheW1lbnQgbXVzdCBiZSB0byBhcHAgYWRkcmVzcwphc3NlcnQKbG9hZCA0OQppdG9iCmxvZwpmcmFtZV9kaWcgLTEKZ3R4bnMgQW1vdW50CmxvYWQgNDkKPT0KLy8gUGF5bWVudCBtdXN0IGJlIGZvciB0aGUgZXhhY3QgbWluIGJhbGFuY2UgcmVxdWlyZW1lbnQKYXNzZXJ0CmJ5dGVjIDkgLy8gIlYiCmJ5dGVjIDggLy8gInRvdGFsX29wdGlvbnMiCmFwcF9nbG9iYWxfZ2V0CnB1c2hpbnQgOCAvLyA4CioKYm94X2NyZWF0ZQpwb3AKY2FsbHN1YiBjcmVhdGVvcHVwXzQKcmV0c3ViCgovLyBjbG9zZQpjbG9zZV83Ogpwcm90byAxIDAKYnl0ZWNfMSAvLyAiIgppbnRjXzAgLy8gMApkdXBuIDIKdHhuIFNlbmRlcgpnbG9iYWwgQ3JlYXRvckFkZHJlc3MKPT0KLy8gdW5hdXRob3JpemVkCmFzc2VydApmcmFtZV9kaWcgLTEKdHhuYXMgQXBwbGljYXRpb25zCmJ5dGVjXzIgLy8gIm91YWlkIgphcHBfZ2xvYmFsX2dldAo9PQovLyBPcFVwIGFwcCBJRCBub3QgcGFzc2VkIGluCmFzc2VydApwdXNoaW50IDIwMDAwIC8vIDIwMDAwCmludGNfMiAvLyAxMAorCnN0b3JlIDUwCmNsb3NlXzdfbDE6CmxvYWQgNTAKZ2xvYmFsIE9wY29kZUJ1ZGdldAo+CmJueiBjbG9zZV83X2wxNwpieXRlYyA3IC8vICJjbG9zZV90aW1lIgphcHBfZ2xvYmFsX2dldAppbnRjXzAgLy8gMAo9PQovLyBBbHJlYWR5IGNsb3NlZAphc3NlcnQKYnl0ZWMgNyAvLyAiY2xvc2VfdGltZSIKZ2xvYmFsIExhdGVzdFRpbWVzdGFtcAphcHBfZ2xvYmFsX3B1dApwdXNoYnl0ZXMgMHg3YjIyNzM3NDYxNmU2NDYxNzI2NDIyM2EyMjYxNzI2MzM2MzkyMjJjMjI2NDY1NzM2MzcyNjk3MDc0Njk2ZjZlMjIzYTIyNTQ2ODY5NzMyMDY5NzMyMDYxMjA3NjZmNzQ2OTZlNjcyMDcyNjU3Mzc1NmM3NDIwNGU0NjU0MjA2NjZmNzIyMDc2NmY3NDY5NmU2NzIwNzI2Zjc1NmU2NDIwNzc2OTc0NjgyMDQ5NDQyMCAvLyAie1wic3RhbmRhcmRcIjpcImFyYzY5XCIsXCJkZXNjcmlwdGlvblwiOlwiVGhpcyBpcyBhIHZvdGluZyByZXN1bHQgTkZUIGZvciB2b3Rpbmcgcm91bmQgd2l0aCBJRCAiCmJ5dGVjXzMgLy8gInZvdGVfaWQiCmFwcF9nbG9iYWxfZ2V0CmNvbmNhdApwdXNoYnl0ZXMgMHgyZTIyMmMyMjcwNzI2ZjcwNjU3Mjc0Njk2NTczMjIzYTdiMjI2ZDY1NzQ2MTY0NjE3NDYxMjIzYTIyNjk3MDY2NzMzYTJmMmYgLy8gIi5cIixcInByb3BlcnRpZXNcIjp7XCJtZXRhZGF0YVwiOlwiaXBmczovLyIKY29uY2F0CmJ5dGVjIDExIC8vICJtZXRhZGF0YV9pcGZzX2NpZCIKYXBwX2dsb2JhbF9nZXQKY29uY2F0CnB1c2hieXRlcyAweDIyMmMyMjY5NjQyMjNhMjIgLy8gIlwiLFwiaWRcIjpcIiIKY29uY2F0CmJ5dGVjXzMgLy8gInZvdGVfaWQiCmFwcF9nbG9iYWxfZ2V0CmNvbmNhdApwdXNoYnl0ZXMgMHgyMjJjMjI3MTc1NmY3Mjc1NmQyMjNhIC8vICJcIixcInF1b3J1bVwiOiIKY29uY2F0CmJ5dGVjIDE0IC8vICJxdW9ydW0iCmFwcF9nbG9iYWxfZ2V0CmNhbGxzdWIgaXRvYV8xCmNvbmNhdApwdXNoYnl0ZXMgMHgyYzIyNzY2Zjc0NjU3MjQzNmY3NTZlNzQyMjNhIC8vICIsXCJ2b3RlckNvdW50XCI6Igpjb25jYXQKYnl0ZWMgNiAvLyAidm90ZXJfY291bnQiCmFwcF9nbG9iYWxfZ2V0CmNhbGxzdWIgaXRvYV8xCmNvbmNhdApwdXNoYnl0ZXMgMHgyYzIyNzQ2MTZjNmM2OTY1NzMyMjNhNWIgLy8gIixcInRhbGxpZXNcIjpbIgpjb25jYXQKc3RvcmUgNTEKYnl0ZWMgNCAvLyAib3B0aW9uX2NvdW50cyIKYXBwX2dsb2JhbF9nZXQKZnJhbWVfYnVyeSAwCmZyYW1lX2RpZyAwCmludGNfMCAvLyAwCmV4dHJhY3RfdWludDE2CmZyYW1lX2J1cnkgMQpmcmFtZV9kaWcgMQpzdG9yZSA1MgppbnRjXzAgLy8gMApzdG9yZSA1MwppbnRjXzAgLy8gMApzdG9yZSA1NAppbnRjXzAgLy8gMApzdG9yZSA1NQpjbG9zZV83X2wzOgpsb2FkIDU1CmxvYWQgNTIKPApieiBjbG9zZV83X2wxOApmcmFtZV9kaWcgMAppbnRjXzEgLy8gMQpsb2FkIDU1CioKcHVzaGludCAyIC8vIDIKKwpnZXRieXRlCmZyYW1lX2J1cnkgMgpmcmFtZV9kaWcgMgpzdG9yZSA1NgppbnRjXzAgLy8gMApzdG9yZSA1NwpjbG9zZV83X2w1Ogpsb2FkIDU3CmxvYWQgNTYKPApibnogY2xvc2VfN19sNwpsb2FkIDU1CmludGNfMSAvLyAxCisKc3RvcmUgNTUKYiBjbG9zZV83X2wzCmNsb3NlXzdfbDc6CnB1c2hpbnQgOCAvLyA4CmxvYWQgNTQKKgpzdG9yZSA1OApieXRlYyA5IC8vICJWIgpsb2FkIDU4CnB1c2hpbnQgOCAvLyA4CmJveF9leHRyYWN0CmJ0b2kKc3RvcmUgNTMKbG9hZCA1MQpsb2FkIDU3CmludGNfMCAvLyAwCj09CmJueiBjbG9zZV83X2wxNgpieXRlY18xIC8vICIiCmNsb3NlXzdfbDk6CmNvbmNhdApsb2FkIDUzCmNhbGxzdWIgaXRvYV8xCmNvbmNhdApsb2FkIDU3CmxvYWQgNTYKaW50Y18xIC8vIDEKLQo9PQpibnogY2xvc2VfN19sMTIKYnl0ZWMgMjAgLy8gIiwiCmNsb3NlXzdfbDExOgpjb25jYXQKc3RvcmUgNTEKbG9hZCA1NAppbnRjXzEgLy8gMQorCnN0b3JlIDU0CmxvYWQgNTcKaW50Y18xIC8vIDEKKwpzdG9yZSA1NwpiIGNsb3NlXzdfbDUKY2xvc2VfN19sMTI6CnB1c2hieXRlcyAweDVkIC8vICJdIgpsb2FkIDU1CmxvYWQgNTIKaW50Y18xIC8vIDEKLQo9PQpibnogY2xvc2VfN19sMTUKYnl0ZWMgMjAgLy8gIiwiCmNsb3NlXzdfbDE0Ogpjb25jYXQKYiBjbG9zZV83X2wxMQpjbG9zZV83X2wxNToKYnl0ZWNfMSAvLyAiIgpiIGNsb3NlXzdfbDE0CmNsb3NlXzdfbDE2OgpwdXNoYnl0ZXMgMHg1YiAvLyAiWyIKYiBjbG9zZV83X2w5CmNsb3NlXzdfbDE3OgppdHhuX2JlZ2luCnB1c2hpbnQgNiAvLyBhcHBsCml0eG5fZmllbGQgVHlwZUVudW0KYnl0ZWNfMiAvLyAib3VhaWQiCmFwcF9nbG9iYWxfZ2V0Cml0eG5fZmllbGQgQXBwbGljYXRpb25JRApieXRlYyAxNiAvLyAib3B1cCgpdm9pZCIKaXR4bl9maWVsZCBBcHBsaWNhdGlvbkFyZ3MKaW50Y18wIC8vIDAKaXR4bl9maWVsZCBGZWUKaXR4bl9zdWJtaXQKYiBjbG9zZV83X2wxCmNsb3NlXzdfbDE4OgppdHhuX2JlZ2luCmludGNfMyAvLyBhY2ZnCml0eG5fZmllbGQgVHlwZUVudW0KaW50Y18xIC8vIDEKaXR4bl9maWVsZCBDb25maWdBc3NldFRvdGFsCmludGNfMCAvLyAwCml0eG5fZmllbGQgQ29uZmlnQXNzZXREZWNpbWFscwppbnRjXzAgLy8gMAppdHhuX2ZpZWxkIENvbmZpZ0Fzc2V0RGVmYXVsdEZyb3plbgpwdXNoYnl0ZXMgMHg1YjU2NGY1NDQ1MjA1MjQ1NTM1NTRjNTQ1ZDIwIC8vICJbVk9URSBSRVNVTFRdICIKYnl0ZWNfMyAvLyAidm90ZV9pZCIKYXBwX2dsb2JhbF9nZXQKY29uY2F0Cml0eG5fZmllbGQgQ29uZmlnQXNzZXROYW1lCnB1c2hieXRlcyAweDU2NGY1NDQ1NTI1MzRjNTQgLy8gIlZPVEVSU0xUIgppdHhuX2ZpZWxkIENvbmZpZ0Fzc2V0VW5pdE5hbWUKYnl0ZWMgMTUgLy8gIm5mdF9pbWFnZV91cmwiCmFwcF9nbG9iYWxfZ2V0Cml0eG5fZmllbGQgQ29uZmlnQXNzZXRVUkwKbG9hZCA1MQpwdXNoYnl0ZXMgMHg1ZDdkN2QgLy8gIl19fSIKY29uY2F0Cml0eG5fZmllbGQgTm90ZQppdHhuX3N1Ym1pdApieXRlYyAxOCAvLyAibmZ0X2Fzc2V0X2lkIgppdHhuIENyZWF0ZWRBc3NldElECmFwcF9nbG9iYWxfcHV0CnJldHN1YgoKLy8gYWxsb3dlZF90b192b3RlCmFsbG93ZWR0b3ZvdGVfODoKcHJvdG8gMyAxCmJ5dGVjXzAgLy8gInZvdGVfdHlwZSIKYXBwX2dsb2JhbF9nZXQKaW50Y18wIC8vIDAKPT0KYm56IGFsbG93ZWR0b3ZvdGVfOF9sOApmcmFtZV9kaWcgLTEKdHhuYXMgQXBwbGljYXRpb25zCmJ5dGVjXzIgLy8gIm91YWlkIgphcHBfZ2xvYmFsX2dldAo9PQovLyBPcFVwIGFwcCBJRCBub3QgcGFzc2VkIGluCmFzc2VydApwdXNoaW50IDIwMDAgLy8gMjAwMAppbnRjXzIgLy8gMTAKKwpzdG9yZSA1OQphbGxvd2VkdG92b3RlXzhfbDI6CmxvYWQgNTkKZ2xvYmFsIE9wY29kZUJ1ZGdldAo+CmJueiBhbGxvd2VkdG92b3RlXzhfbDcKYnl0ZWNfMCAvLyAidm90ZV90eXBlIgphcHBfZ2xvYmFsX2dldAppbnRjXzEgLy8gMQo9PQpibnogYWxsb3dlZHRvdm90ZV84X2w2CnR4biBTZW5kZXIKZnJhbWVfZGlnIC0yCml0b2IKY29uY2F0CmFsbG93ZWR0b3ZvdGVfOF9sNToKZnJhbWVfZGlnIC0zCmJ5dGVjIDEwIC8vICJzbmFwc2hvdF9wdWJsaWNfa2V5IgphcHBfZ2xvYmFsX2dldAplZDI1NTE5dmVyaWZ5X2JhcmUKYiBhbGxvd2VkdG92b3RlXzhfbDkKYWxsb3dlZHRvdm90ZV84X2w2Ogp0eG4gU2VuZGVyCmIgYWxsb3dlZHRvdm90ZV84X2w1CmFsbG93ZWR0b3ZvdGVfOF9sNzoKaXR4bl9iZWdpbgpwdXNoaW50IDYgLy8gYXBwbAppdHhuX2ZpZWxkIFR5cGVFbnVtCmJ5dGVjXzIgLy8gIm91YWlkIgphcHBfZ2xvYmFsX2dldAppdHhuX2ZpZWxkIEFwcGxpY2F0aW9uSUQKYnl0ZWMgMTYgLy8gIm9wdXAoKXZvaWQiCml0eG5fZmllbGQgQXBwbGljYXRpb25BcmdzCmludGNfMCAvLyAwCml0eG5fZmllbGQgRmVlCml0eG5fc3VibWl0CmIgYWxsb3dlZHRvdm90ZV84X2wyCmFsbG93ZWR0b3ZvdGVfOF9sODoKaW50Y18xIC8vIDEKYWxsb3dlZHRvdm90ZV84X2w5OgpyZXRzdWIKCi8vIHZvdGluZ19vcGVuCnZvdGluZ29wZW5fOToKcHJvdG8gMCAxCmJ5dGVjIDUgLy8gImlzX2Jvb3RzdHJhcHBlZCIKYXBwX2dsb2JhbF9nZXQKaW50Y18xIC8vIDEKPT0KYnl0ZWMgNyAvLyAiY2xvc2VfdGltZSIKYXBwX2dsb2JhbF9nZXQKaW50Y18wIC8vIDAKPT0KJiYKZ2xvYmFsIExhdGVzdFRpbWVzdGFtcApieXRlYyAxMiAvLyAic3RhcnRfdGltZSIKYXBwX2dsb2JhbF9nZXQKPj0KJiYKZ2xvYmFsIExhdGVzdFRpbWVzdGFtcApieXRlYyAxMyAvLyAiZW5kX3RpbWUiCmFwcF9nbG9iYWxfZ2V0CjwKJiYKcmV0c3ViCgovLyBhbHJlYWR5X3ZvdGVkCmFscmVhZHl2b3RlZF8xMDoKcHJvdG8gMCAxCmJ5dGVjXzEgLy8gIiIKdHhuIFNlbmRlcgpmcmFtZV9idXJ5IDAKZnJhbWVfZGlnIDAKbGVuCnB1c2hpbnQgMzIgLy8gMzIKPT0KYXNzZXJ0CmZyYW1lX2RpZyAwCmJveF9sZW4Kc3RvcmUgNjEKc3RvcmUgNjAKbG9hZCA2MQpmcmFtZV9idXJ5IDAKcmV0c3ViCgovLyBnZXRfcHJlY29uZGl0aW9ucwpnZXRwcmVjb25kaXRpb25zXzExOgpwcm90byAzIDEKYnl0ZWNfMSAvLyAiIgppbnRjXzAgLy8gMApkdXBuIDUKYnl0ZWNfMSAvLyAiIgpkdXAKY2FsbHN1YiB2b3RpbmdvcGVuXzkKZnJhbWVfYnVyeSAxCmZyYW1lX2RpZyAtMwpleHRyYWN0IDIgMApmcmFtZV9kaWcgLTIKZnJhbWVfZGlnIC0xCmNhbGxzdWIgYWxsb3dlZHRvdm90ZV84CmZyYW1lX2J1cnkgMgpjYWxsc3ViIGFscmVhZHl2b3RlZF8xMApmcmFtZV9idXJ5IDMKZ2xvYmFsIExhdGVzdFRpbWVzdGFtcApmcmFtZV9idXJ5IDQKZnJhbWVfZGlnIDEKaXRvYgpmcmFtZV9kaWcgMgppdG9iCmNvbmNhdApmcmFtZV9kaWcgMwppdG9iCmNvbmNhdApmcmFtZV9kaWcgNAppdG9iCmNvbmNhdApmcmFtZV9idXJ5IDAKcmV0c3ViCgovLyB2b3RlCnZvdGVfMTI6CnByb3RvIDYgMApieXRlY18xIC8vICIiCmludGNfMCAvLyAwCmR1cG4gMTEKYnl0ZWNfMSAvLyAiIgpmcmFtZV9kaWcgLTEKdHhuYXMgQXBwbGljYXRpb25zCmJ5dGVjXzIgLy8gIm91YWlkIgphcHBfZ2xvYmFsX2dldAo9PQovLyBPcFVwIGFwcCBJRCBub3QgcGFzc2VkIGluCmFzc2VydApmcmFtZV9kaWcgLTUKZXh0cmFjdCAyIDAKZnJhbWVfZGlnIC00CmZyYW1lX2RpZyAtMQpjYWxsc3ViIGFsbG93ZWR0b3ZvdGVfOAovLyBOb3QgYWxsb3dlZCB0byB2b3RlCmFzc2VydApjYWxsc3ViIHZvdGluZ29wZW5fOQovLyBWb3Rpbmcgbm90IG9wZW4KYXNzZXJ0CmNhbGxzdWIgYWxyZWFkeXZvdGVkXzEwCiEKLy8gQWxyZWFkeSB2b3RlZAphc3NlcnQKYnl0ZWMgNCAvLyAib3B0aW9uX2NvdW50cyIKYXBwX2dsb2JhbF9nZXQKZnJhbWVfYnVyeSAwCmZyYW1lX2RpZyAwCmludGNfMCAvLyAwCmV4dHJhY3RfdWludDE2CmZyYW1lX2J1cnkgMQpmcmFtZV9kaWcgMQpzdG9yZSA2MgpmcmFtZV9kaWcgLTMKaW50Y18wIC8vIDAKZXh0cmFjdF91aW50MTYKZnJhbWVfYnVyeSAyCmZyYW1lX2RpZyAyCmxvYWQgNjIKPT0KLy8gTnVtYmVyIG9mIGFuc3dlcnMgaW5jb3JyZWN0CmFzc2VydApieXRlY18wIC8vICJ2b3RlX3R5cGUiCmFwcF9nbG9iYWxfZ2V0CmludGNfMyAvLyAzCj09CmJueiB2b3RlXzEyX2wyMApmcmFtZV9kaWcgLTIKaW50Y18wIC8vIDAKZXh0cmFjdF91aW50MTYKZnJhbWVfYnVyeSA0CmZyYW1lX2RpZyA0CmludGNfMCAvLyAwCj09Ci8vIE51bWJlciBvZiBhbnN3ZXIgd2VpZ2h0cyBzaG91bGQgYmUgMCBzaW5jZSB0aGlzIHZvdGUgZG9lc24ndCB1c2UgcGFydGl0aW9uZWQgd2VpZ2h0aW5nCmFzc2VydAp2b3RlXzEyX2wyOgpwdXNoaW50IDI1MDAgLy8gMjUwMApwdXNoaW50IDM0IC8vIDM0CmludGNfMSAvLyAxCmZyYW1lX2RpZyAtMwppbnRjXzAgLy8gMApleHRyYWN0X3VpbnQxNgpmcmFtZV9idXJ5IDYKZnJhbWVfZGlnIDYKKgorCnB1c2hpbnQgNDAwIC8vIDQwMAoqCisKc3RvcmUgNjMKZnJhbWVfZGlnIC02Cmd0eG5zIFJlY2VpdmVyCmdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCj09Ci8vIFBheW1lbnQgbXVzdCBiZSB0byBhcHAgYWRkcmVzcwphc3NlcnQKbG9hZCA2MwppdG9iCmxvZwpmcmFtZV9kaWcgLTYKZ3R4bnMgQW1vdW50CmxvYWQgNjMKPT0KLy8gUGF5bWVudCBtdXN0IGJlIHRoZSBleGFjdCBtaW4gYmFsYW5jZSByZXF1aXJlbWVudAphc3NlcnQKaW50Y18wIC8vIDAKc3RvcmUgNjQKaW50Y18wIC8vIDAKc3RvcmUgNjUKaW50Y18wIC8vIDAKc3RvcmUgNjYKdm90ZV8xMl9sMzoKbG9hZCA2Ngpsb2FkIDYyCjwKYm56IHZvdGVfMTJfbDYKYnl0ZWNfMCAvLyAidm90ZV90eXBlIgphcHBfZ2xvYmFsX2dldAppbnRjXzMgLy8gMwo9PQpieiB2b3RlXzEyX2wyMQpsb2FkIDY1CmZyYW1lX2RpZyAtNAo9PQovLyBEaWRuJ3QgcGFydGl0aW9uIGV4YWN0IHZvdGluZyB3ZWlnaHQgYWNyb3NzIHF1ZXN0aW9ucwphc3NlcnQKYiB2b3RlXzEyX2wyMQp2b3RlXzEyX2w2OgpnbG9iYWwgT3Bjb2RlQnVkZ2V0CnB1c2hpbnQgMTAwIC8vIDEwMAo8CmJueiB2b3RlXzEyX2wxNwp2b3RlXzEyX2w3OgpmcmFtZV9kaWcgLTMKaW50Y18xIC8vIDEKbG9hZCA2NgoqCnB1c2hpbnQgMiAvLyAyCisKZ2V0Ynl0ZQpmcmFtZV9idXJ5IDcKaW50Y18wIC8vIDAKZnJhbWVfYnVyeSA5CmJ5dGVjXzAgLy8gInZvdGVfdHlwZSIKYXBwX2dsb2JhbF9nZXQKaW50Y18zIC8vIDMKPT0KYm56IHZvdGVfMTJfbDE2CnZvdGVfMTJfbDg6CmZyYW1lX2RpZyAwCmludGNfMSAvLyAxCmxvYWQgNjYKKgpwdXNoaW50IDIgLy8gMgorCmdldGJ5dGUKZnJhbWVfYnVyeSAxMQpmcmFtZV9kaWcgNwpmcmFtZV9kaWcgMTEKPAovLyBBbnN3ZXIgb3B0aW9uIGluZGV4IGludmFsaWQKYXNzZXJ0CnB1c2hpbnQgOCAvLyA4CmxvYWQgNjQKZnJhbWVfZGlnIDcKKwoqCnN0b3JlIDY4CmJ5dGVjIDkgLy8gIlYiCmxvYWQgNjgKcHVzaGludCA4IC8vIDgKYm94X2V4dHJhY3QKYnRvaQpzdG9yZSA2OQpieXRlYyA5IC8vICJWIgpsb2FkIDY4CmxvYWQgNjkKYnl0ZWNfMCAvLyAidm90ZV90eXBlIgphcHBfZ2xvYmFsX2dldAppbnRjXzAgLy8gMAo9PQpieXRlY18wIC8vICJ2b3RlX3R5cGUiCmFwcF9nbG9iYWxfZ2V0CmludGNfMSAvLyAxCj09Cnx8CmJueiB2b3RlXzEyX2wxNQpieXRlY18wIC8vICJ2b3RlX3R5cGUiCmFwcF9nbG9iYWxfZ2V0CnB1c2hpbnQgMiAvLyAyCj09CmJueiB2b3RlXzEyX2wxNApmcmFtZV9kaWcgOQp2b3RlXzEyX2wxMToKKwppdG9iCmJveF9yZXBsYWNlCmxvYWQgNjQKZnJhbWVfZGlnIDExCisKc3RvcmUgNjQKYnl0ZWNfMCAvLyAidm90ZV90eXBlIgphcHBfZ2xvYmFsX2dldAppbnRjXzMgLy8gMwo9PQpibnogdm90ZV8xMl9sMTMKdm90ZV8xMl9sMTI6CmxvYWQgNjYKaW50Y18xIC8vIDEKKwpzdG9yZSA2NgpiIHZvdGVfMTJfbDMKdm90ZV8xMl9sMTM6CmxvYWQgNjUKZnJhbWVfZGlnIDkKKwpzdG9yZSA2NQpiIHZvdGVfMTJfbDEyCnZvdGVfMTJfbDE0OgpmcmFtZV9kaWcgLTQKYiB2b3RlXzEyX2wxMQp2b3RlXzEyX2wxNToKaW50Y18xIC8vIDEKYiB2b3RlXzEyX2wxMQp2b3RlXzEyX2wxNjoKZnJhbWVfZGlnIC0yCnB1c2hpbnQgOCAvLyA4CmxvYWQgNjYKKgpwdXNoaW50IDIgLy8gMgorCmV4dHJhY3RfdWludDY0CmZyYW1lX2J1cnkgOQpiIHZvdGVfMTJfbDgKdm90ZV8xMl9sMTc6CnB1c2hpbnQgNjgwIC8vIDY4MAppbnRjXzIgLy8gMTAKKwpzdG9yZSA2Nwp2b3RlXzEyX2wxODoKbG9hZCA2NwpnbG9iYWwgT3Bjb2RlQnVkZ2V0Cj4KYnogdm90ZV8xMl9sNwppdHhuX2JlZ2luCnB1c2hpbnQgNiAvLyBhcHBsCml0eG5fZmllbGQgVHlwZUVudW0KYnl0ZWNfMiAvLyAib3VhaWQiCmFwcF9nbG9iYWxfZ2V0Cml0eG5fZmllbGQgQXBwbGljYXRpb25JRApieXRlYyAxNiAvLyAib3B1cCgpdm9pZCIKaXR4bl9maWVsZCBBcHBsaWNhdGlvbkFyZ3MKaW50Y18wIC8vIDAKaXR4bl9maWVsZCBGZWUKaXR4bl9zdWJtaXQKYiB2b3RlXzEyX2wxOAp2b3RlXzEyX2wyMDoKZnJhbWVfZGlnIC0yCmludGNfMCAvLyAwCmV4dHJhY3RfdWludDE2CmZyYW1lX2J1cnkgMwpmcmFtZV9kaWcgMwpsb2FkIDYyCj09Ci8vIE51bWJlciBvZiBhbnN3ZXIgd2VpZ2h0cyBpbmNvcnJlY3QsIHNob3VsZCBtYXRjaCBudW1iZXIgb2YgcXVlc3Rpb25zIHNpbmNlIHRoaXMgdm90ZSB1c2VzIHBhcnRpdGlvbmVkIHdlaWdodGluZwphc3NlcnQKYiB2b3RlXzEyX2wyCnZvdGVfMTJfbDIxOgp0eG4gU2VuZGVyCmZyYW1lX2J1cnkgMTMKZnJhbWVfZGlnIDEzCmxlbgpwdXNoaW50IDMyIC8vIDMyCj09CmFzc2VydApmcmFtZV9kaWcgMTMKYm94X2RlbApwb3AKZnJhbWVfZGlnIDEzCmZyYW1lX2RpZyAtMwpib3hfcHV0CmJ5dGVjIDYgLy8gInZvdGVyX2NvdW50IgpieXRlYyA2IC8vICJ2b3Rlcl9jb3VudCIKYXBwX2dsb2JhbF9nZXQKaW50Y18xIC8vIDEKKwphcHBfZ2xvYmFsX3B1dApyZXRzdWI=","clear":"I3ByYWdtYSB2ZXJzaW9uIDgKcHVzaGludCAwIC8vIDAKcmV0dXJu"},"bareActions":{"create":[],"call":["DeleteApplication"]}} as unknown as Arc56Contract -/** - * Defines an onCompletionAction of 'no_op' - */ -export type OnCompleteNoOp = { onCompleteAction?: 'no_op' | OnApplicationComplete.NoOpOC } -/** - * Defines an onCompletionAction of 'opt_in' - */ -export type OnCompleteOptIn = { onCompleteAction: 'opt_in' | OnApplicationComplete.OptInOC } -/** - * Defines an onCompletionAction of 'close_out' - */ -export type OnCompleteCloseOut = { onCompleteAction: 'close_out' | OnApplicationComplete.CloseOutOC } -/** - * Defines an onCompletionAction of 'delete_application' - */ -export type OnCompleteDelApp = { onCompleteAction: 'delete_application' | OnApplicationComplete.DeleteApplicationOC } -/** - * Defines an onCompletionAction of 'update_application' - */ -export type OnCompleteUpdApp = { onCompleteAction: 'update_application' | OnApplicationComplete.UpdateApplicationOC } -/** - * A state record containing a single unsigned integer - */ -export type IntegerState = { - /** - * Gets the state value as a BigInt. - */ - asBigInt(): bigint - /** - * Gets the state value as a number. - */ - asNumber(): number -} /** * A state record containing binary data */ -export type BinaryState = { +export interface BinaryState { /** * Gets the state value as a Uint8Array */ - asByteArray(): Uint8Array + asByteArray(): Uint8Array | undefined /** * Gets the state value as a string */ - asString(): string + asString(): string | undefined } -export type AppCreateCallTransactionResult = AppCallTransactionResult & Partial & AppReference -export type AppUpdateCallTransactionResult = AppCallTransactionResult & Partial +class BinaryStateValue implements BinaryState { + constructor(private value: Uint8Array | undefined) {} -export type AppClientComposeCallCoreParams = Omit & { - sendParams?: Omit< - SendTransactionParams, - 'skipSending' | 'atc' | 'skipWaiting' | 'maxRoundsToWaitForConfirmation' | 'populateAppCallResources' - > + asByteArray(): Uint8Array | undefined { + return this.value + } + + asString(): string | undefined { + return this.value !== undefined ? Buffer.from(this.value).toString('utf-8') : undefined + } } -export type AppClientComposeExecuteParams = Pick< - SendTransactionParams, - 'skipWaiting' | 'maxRoundsToWaitForConfirmation' | 'populateAppCallResources' | 'suppressLog' -> -export type IncludeSchema = { +/** + * Expands types for IntelliSense so they are more human readable + * See https://stackoverflow.com/a/69288824 + */ +export type Expand = T extends (...args: infer A) => infer R + ? (...args: Expand) => Expand + : T extends infer O + ? { [K in keyof O]: O[K] } + : never + + +// Type definitions for ARC-56 structs + +export type VotingPreconditions = { + isVotingOpen: bigint, + isAllowedToVote: bigint, + hasAlreadyVoted: bigint, + currentTime: bigint +} + + +/** + * Converts the ABI tuple representation of a VotingPreconditions to the struct representation + */ +export function VotingPreconditionsFromTuple(abiTuple: [bigint, bigint, bigint, bigint]) { + return getABIStructFromABITuple(abiTuple, APP_SPEC.structs.VotingPreconditions, APP_SPEC.structs) as VotingPreconditions +} + +/** + * The argument types for the VotingRoundApp contract + */ +export type VotingRoundAppArgs = { /** - * Any overrides for the storage schema to request for the created app; by default the schema indicated by the app spec is used. + * The object representation of the arguments for each method */ - schema?: Partial + obj: { + 'opup_bootstrap(pay)uint64': { + ptxn: AppMethodCallTransactionArgument + } + 'create(string,uint8,byte[],string,uint64,uint64,uint8[],uint64,string)void': { + voteId: string + voteType: bigint | number + snapshotPublicKey: Uint8Array + metadataIpfsCid: string + startTime: bigint | number + endTime: bigint | number + optionCounts: bigint | number[] + quorum: bigint | number + nftImageUrl: string + } + 'bootstrap(pay)void': { + fundMinBalReq: AppMethodCallTransactionArgument + } + 'close(application)void': { + opupApp?: bigint + } + 'get_preconditions(byte[],uint64,application)(uint64,uint64,uint64,uint64)': { + signature: Uint8Array + weighting: bigint | number + opupApp?: bigint + } + 'vote(pay,byte[],uint64,uint8[],uint64[],application)void': { + fundMinBalReq: AppMethodCallTransactionArgument + signature: Uint8Array + weighting: bigint | number + answerIds: bigint | number[] + answerWeights: bigint | number[] + opupApp?: bigint + } + } + /** + * The tuple representation of the arguments for each method + */ + tuple: { + 'opup_bootstrap(pay)uint64': [ptxn: AppMethodCallTransactionArgument] + 'create(string,uint8,byte[],string,uint64,uint64,uint8[],uint64,string)void': [voteId: string, voteType: bigint | number, snapshotPublicKey: Uint8Array, metadataIpfsCid: string, startTime: bigint | number, endTime: bigint | number, optionCounts: bigint | number[], quorum: bigint | number, nftImageUrl: string] + 'bootstrap(pay)void': [fundMinBalReq: AppMethodCallTransactionArgument] + 'close(application)void': [opupApp: bigint | undefined] + 'get_preconditions(byte[],uint64,application)(uint64,uint64,uint64,uint64)': [signature: Uint8Array, weighting: bigint | number, opupApp: bigint | undefined] + 'vote(pay,byte[],uint64,uint8[],uint64[],application)void': [fundMinBalReq: AppMethodCallTransactionArgument, signature: Uint8Array, weighting: bigint | number, answerIds: bigint | number[], answerWeights: bigint | number[], opupApp: bigint | undefined] + } +} + +/** + * The return type for each method + */ +export type VotingRoundAppReturns = { + 'opup_bootstrap(pay)uint64': bigint + 'create(string,uint8,byte[],string,uint64,uint64,uint8[],uint64,string)void': void + 'bootstrap(pay)void': void + 'close(application)void': void + 'get_preconditions(byte[],uint64,application)(uint64,uint64,uint64,uint64)': VotingPreconditions + 'vote(pay,byte[],uint64,uint8[],uint64[],application)void': void } /** * Defines the types of available calls and state of the VotingRoundApp smart contract. */ -export type VotingRoundApp = { +export type VotingRoundAppTypes = { /** * Maps method signatures / names to their argument and return types. */ - methods: Record< - 'opup_bootstrap(pay)uint64' | 'opup_bootstrap', - { - argsObj: { - ptxn: TransactionToSign | Transaction | Promise - } - argsTuple: [ptxn: TransactionToSign | Transaction | Promise] - returns: bigint - } - > & - Record< - 'create(string,uint8,byte[],string,uint64,uint64,uint8[],uint64,string)void' | 'create', - { - argsObj: { - voteId: string - voteType: number - snapshotPublicKey: Uint8Array - metadataIpfsCid: string - startTime: bigint | number - endTime: bigint | number - optionCounts: number[] - quorum: bigint | number - nftImageUrl: string - } - argsTuple: [ - voteId: string, - voteType: number, - snapshotPublicKey: Uint8Array, - metadataIpfsCid: string, - startTime: bigint | number, - endTime: bigint | number, - optionCounts: number[], - quorum: bigint | number, - nftImageUrl: string, - ] - returns: void - } - > & - Record< - 'bootstrap(pay)void' | 'bootstrap', - { - argsObj: { - fundMinBalReq: TransactionToSign | Transaction | Promise - } - argsTuple: [fundMinBalReq: TransactionToSign | Transaction | Promise] - returns: void - } - > & - Record< - 'close(application)void' | 'close', - { - argsObj: { - opupApp?: number | bigint - } - argsTuple: [opupApp: number | bigint | undefined] - returns: void - } - > & - Record< - 'get_preconditions(byte[],uint64,application)(uint64,uint64,uint64,uint64)' | 'get_preconditions', - { - argsObj: { - signature: Uint8Array - weighting: bigint | number - opupApp?: number | bigint - } - argsTuple: [signature: Uint8Array, weighting: bigint | number, opupApp: number | bigint | undefined] - returns: VotingPreconditions - } - > & - Record< - 'vote(pay,byte[],uint64,uint8[],uint64[],application)void' | 'vote', - { - argsObj: { - fundMinBalReq: TransactionToSign | Transaction | Promise - signature: Uint8Array - weighting: bigint | number - answerIds: number[] - answerWeights: bigint | number[] - opupApp?: number | bigint - } - argsTuple: [ - fundMinBalReq: TransactionToSign | Transaction | Promise, - signature: Uint8Array, - weighting: bigint | number, - answerIds: number[], - answerWeights: bigint | number[], - opupApp: number | bigint | undefined, - ] - returns: void - } - > + methods: + & Record<'opup_bootstrap(pay)uint64' | 'opup_bootstrap', { + argsObj: VotingRoundAppArgs['obj']['opup_bootstrap(pay)uint64'] + argsTuple: VotingRoundAppArgs['tuple']['opup_bootstrap(pay)uint64'] + returns: VotingRoundAppReturns['opup_bootstrap(pay)uint64'] + }> + & Record<'create(string,uint8,byte[],string,uint64,uint64,uint8[],uint64,string)void' | 'create', { + argsObj: VotingRoundAppArgs['obj']['create(string,uint8,byte[],string,uint64,uint64,uint8[],uint64,string)void'] + argsTuple: VotingRoundAppArgs['tuple']['create(string,uint8,byte[],string,uint64,uint64,uint8[],uint64,string)void'] + returns: VotingRoundAppReturns['create(string,uint8,byte[],string,uint64,uint64,uint8[],uint64,string)void'] + }> + & Record<'bootstrap(pay)void' | 'bootstrap', { + argsObj: VotingRoundAppArgs['obj']['bootstrap(pay)void'] + argsTuple: VotingRoundAppArgs['tuple']['bootstrap(pay)void'] + returns: VotingRoundAppReturns['bootstrap(pay)void'] + }> + & Record<'close(application)void' | 'close', { + argsObj: VotingRoundAppArgs['obj']['close(application)void'] + argsTuple: VotingRoundAppArgs['tuple']['close(application)void'] + returns: VotingRoundAppReturns['close(application)void'] + }> + & Record<'get_preconditions(byte[],uint64,application)(uint64,uint64,uint64,uint64)' | 'get_preconditions', { + argsObj: VotingRoundAppArgs['obj']['get_preconditions(byte[],uint64,application)(uint64,uint64,uint64,uint64)'] + argsTuple: VotingRoundAppArgs['tuple']['get_preconditions(byte[],uint64,application)(uint64,uint64,uint64,uint64)'] + returns: VotingRoundAppReturns['get_preconditions(byte[],uint64,application)(uint64,uint64,uint64,uint64)'] + }> + & Record<'vote(pay,byte[],uint64,uint8[],uint64[],application)void' | 'vote', { + argsObj: VotingRoundAppArgs['obj']['vote(pay,byte[],uint64,uint8[],uint64[],application)void'] + argsTuple: VotingRoundAppArgs['tuple']['vote(pay,byte[],uint64,uint8[],uint64[],application)void'] + returns: VotingRoundAppReturns['vote(pay,byte[],uint64,uint8[],uint64[],application)void'] + }> /** - * Defines the shape of the global and local state of the application. + * Defines the shape of the state of the application. */ state: { global: { - /** - * The unix timestamp of the time the vote was closed - */ - closeTime?: IntegerState - /** - * The unix timestamp of the ending time of voting - */ - endTime?: IntegerState - /** - * Whether or not the contract has been bootstrapped with answers - */ - isBootstrapped?: IntegerState - /** - * The IPFS content ID of the voting metadata file - */ - metadataIpfsCid?: BinaryState - /** - * The asset ID of a result NFT if one has been created - */ - nftAssetId?: IntegerState - /** - * The IPFS URL of the default image to use as the media of the result NFT - */ - nftImageUrl?: BinaryState - /** - * The number of options for each question - */ - optionCounts?: BinaryState - ouaid?: IntegerState - /** - * The minimum number of voters to reach quorum - */ - quorum?: IntegerState - /** - * The public key of the Ed25519 compatible private key that was used to encrypt entries in the vote gating snapshot - */ - snapshotPublicKey?: BinaryState - /** - * The unix timestamp of the starting time of voting - */ - startTime?: IntegerState - /** - * The total number of options - */ - totalOptions?: IntegerState - /** - * The identifier of this voting round - */ - voteId?: BinaryState - /** - * The type of this voting round; 0 = no snapshot / weighting, 1 = snapshot & no weighting, 2 = snapshot & weighting per question, 3 = snapshot & weighting partitioned across the questions - */ - voteType?: IntegerState - /** - * The minimum number of voters who have voted - */ - voterCount?: IntegerState + keys: { + /** + * The unix timestamp of the time the vote was closed + */ + closeTime: bigint + /** + * The unix timestamp of the ending time of voting + */ + endTime: bigint + /** + * Whether or not the contract has been bootstrapped with answers + */ + isBootstrapped: bigint + /** + * The IPFS content ID of the voting metadata file + */ + metadataIpfsCid: BinaryState + /** + * The asset ID of a result NFT if one has been created + */ + nftAssetId: bigint + /** + * The IPFS URL of the default image to use as the media of the result NFT + */ + nftImageUrl: BinaryState + /** + * The number of options for each question + */ + optionCounts: BinaryState + opupAppId: bigint + /** + * The minimum number of voters to reach quorum + */ + quorum: bigint + /** + * The public key of the Ed25519 compatible private key that was used to encrypt entries in the vote gating snapshot + */ + snapshotPublicKey: BinaryState + /** + * The unix timestamp of the starting time of voting + */ + startTime: bigint + /** + * The total number of options + */ + totalOptions: bigint + /** + * The identifier of this voting round + */ + voteId: BinaryState + /** + * The type of this voting round; 0 = no snapshot / weighting, 1 = snapshot & no weighting, 2 = snapshot & weighting per question, 3 = snapshot & weighting partitioned across the questions + */ + voteType: bigint + /** + * The minimum number of voters who have voted + */ + voterCount: bigint + } } } } + /** - * Defines the possible abi call signatures - */ -export type VotingRoundAppSig = keyof VotingRoundApp['methods'] -/** - * Defines an object containing all relevant parameters for a single call to the contract. Where TSignature is undefined, a bare call is made - */ -export type TypedCallParams = { - method: TSignature - methodArgs: TSignature extends undefined ? undefined : Array -} & AppClientCallCoreParams & - CoreAppCallArgs -/** - * Defines the arguments required for a bare call + * Defines the possible abi call signatures. */ -export type BareCallArgs = Omit +export type VotingRoundAppSignatures = keyof VotingRoundAppTypes['methods'] /** - * Represents a VotingPreconditions result as a struct + * Defines the possible abi call signatures for methods that return a non-void value. */ -export type VotingPreconditions = { - isVotingOpen: bigint - isAllowedToVote: bigint - hasAlreadyVoted: bigint - currentTime: bigint -} +export type VotingRoundAppNonVoidMethodSignatures = keyof VotingRoundAppTypes['methods'] extends infer T ? T extends keyof VotingRoundAppTypes['methods'] ? MethodReturn extends void ? never : T : never : never /** - * Converts the tuple representation of a VotingPreconditions to the struct representation + * Defines an object containing all relevant parameters for a single call to the contract. */ -export function VotingPreconditions([isVotingOpen, isAllowedToVote, hasAlreadyVoted, currentTime]: [bigint, bigint, bigint, bigint]) { - return { - isVotingOpen, - isAllowedToVote, - hasAlreadyVoted, - currentTime, - } -} +export type CallParams = Expand< + Omit & + { + /** The args for the ABI method call, either as an ordered array or an object */ + args: Expand + } +> /** - * Maps a method signature from the VotingRoundApp smart contract to the method's arguments in either tuple of struct form + * Maps a method signature from the VotingRoundApp smart contract to the method's arguments in either tuple or struct form */ -export type MethodArgs = VotingRoundApp['methods'][TSignature]['argsObj' | 'argsTuple'] +export type MethodArgs = VotingRoundAppTypes['methods'][TSignature]['argsObj' | 'argsTuple'] /** * Maps a method signature from the VotingRoundApp smart contract to the method's return type */ -export type MethodReturn = VotingRoundApp['methods'][TSignature]['returns'] +export type MethodReturn = VotingRoundAppTypes['methods'][TSignature]['returns'] /** - * A factory for available 'create' calls - */ -export type VotingRoundAppCreateCalls = (typeof VotingRoundAppCallFactory)['create'] -/** - * Defines supported create methods for this smart contract + * Defines the shape of the keyed global state of the application. */ -export type VotingRoundAppCreateCallParams = TypedCallParams<'create(string,uint8,byte[],string,uint64,uint64,uint8[],uint64,string)void'> & - OnCompleteNoOp +export type GlobalKeysState = VotingRoundAppTypes['state']['global']['keys'] + + /** - * A factory for available 'delete' calls + * Defines supported create method params for this smart contract */ -export type VotingRoundAppDeleteCalls = (typeof VotingRoundAppCallFactory)['delete'] +export type VotingRoundAppCreateCallParams = + | Expand & {method: 'create'} & {onComplete?: OnApplicationComplete.NoOpOC} & CreateSchema> + | Expand & {method: 'create(string,uint8,byte[],string,uint64,uint64,uint8[],uint64,string)void'} & {onComplete?: OnApplicationComplete.NoOpOC} & CreateSchema> /** - * Defines supported delete methods for this smart contract + * Defines supported delete method params for this smart contract */ -export type VotingRoundAppDeleteCallParams = TypedCallParams +export type VotingRoundAppDeleteCallParams = + | Expand & {method?: undefined} /** * Defines arguments required for the deploy method. */ -export type VotingRoundAppDeployArgs = { - deployTimeParams?: TealTemplateParams +export type VotingRoundAppDeployParams = Expand & { /** - * A delegate which takes a create call factory and returns the create call params for this smart contract + * Create transaction parameters to use if a create needs to be issued as part of deployment; use `method` to define ABI call (if available) or leave out for a bare call (if available) */ - createCall?: (callFactory: VotingRoundAppCreateCalls) => VotingRoundAppCreateCallParams + createParams?: VotingRoundAppCreateCallParams /** - * A delegate which takes a delete call factory and returns the delete call params for this smart contract + * Delete transaction parameters to use if a create needs to be issued as part of deployment; use `method` to define ABI call (if available) or leave out for a bare call (if available) */ - deleteCall?: (callFactory: VotingRoundAppDeleteCalls) => VotingRoundAppDeleteCallParams -} + deleteParams?: VotingRoundAppDeleteCallParams +}> + /** - * Exposes methods for constructing all available smart contract calls + * Exposes methods for constructing `AppClient` params objects for ABI calls to the VotingRoundApp smart contract */ -export abstract class VotingRoundAppCallFactory { +export abstract class VotingRoundAppParamsFactory { /** - * Gets available create call factories + * Gets available create ABI call param factories */ static get create() { return { - /** - * Constructs a create call for the VotingRoundApp smart contract using the create(string,uint8,byte[],string,uint64,uint64,uint8[],uint64,string)void ABI method - * - * @param args Any args for the contract call - * @param params Any additional parameters for the call - * @returns A TypedCallParams object for the call - */ - create( - args: MethodArgs<'create(string,uint8,byte[],string,uint64,uint64,uint8[],uint64,string)void'>, - params: AppClientCallCoreParams & CoreAppCallArgs & AppClientCompilationParams & OnCompleteNoOp = {}, - ) { - return { - method: 'create(string,uint8,byte[],string,uint64,uint64,uint8[],uint64,string)void' as const, - methodArgs: Array.isArray(args) - ? args - : [ - args.voteId, - args.voteType, - args.snapshotPublicKey, - args.metadataIpfsCid, - args.startTime, - args.endTime, - args.optionCounts, - args.quorum, - args.nftImageUrl, - ], - ...params, + _resolveByMethod(params: TParams) { + switch(params.method) { + case 'create': + case 'create(string,uint8,byte[],string,uint64,uint64,uint8[],uint64,string)void': + return VotingRoundAppParamsFactory.create.create(params) } + throw new Error(`Unknown ' + verb + ' method`) }, - } - } - /** - * Gets available delete call factories - */ - static get delete() { - return { /** - * Constructs a delete call for the VotingRoundApp smart contract using a bare call + * Constructs create ABI call params for the VotingRoundApp smart contract using the create(string,uint8,byte[],string,uint64,uint64,uint8[],uint64,string)void ABI method * - * @param params Any parameters for the call - * @returns A TypedCallParams object for the call + * @param params Parameters for the call + * @returns An `AppClientMethodCallParams` object for the call */ - bare(params: BareCallArgs & AppClientCallCoreParams & CoreAppCallArgs = {}) { + create(params: CallParams & AppClientCompilationParams & {onComplete?: OnApplicationComplete.NoOpOC}): AppClientMethodCallParams & AppClientCompilationParams & {onComplete?: OnApplicationComplete.NoOpOC} { return { - method: undefined, - methodArgs: undefined, ...params, + method: 'create(string,uint8,byte[],string,uint64,uint64,uint8[],uint64,string)void' as const, + args: Array.isArray(params.args) ? params.args : [params.args.voteId, params.args.voteType, params.args.snapshotPublicKey, params.args.metadataIpfsCid, params.args.startTime, params.args.endTime, params.args.optionCounts, params.args.quorum, params.args.nftImageUrl], } }, } @@ -718,147 +351,131 @@ export abstract class VotingRoundAppCallFactory { * * initialize opup with bootstrap to create a target app * - * @param args Any args for the contract call - * @param params Any additional parameters for the call - * @returns A TypedCallParams object for the call + * @param params Parameters for the call + * @returns An `AppClientMethodCallParams` object for the call */ - static opupBootstrap(args: MethodArgs<'opup_bootstrap(pay)uint64'>, params: AppClientCallCoreParams & CoreAppCallArgs) { + static opupBootstrap(params: CallParams & CallOnComplete): AppClientMethodCallParams & CallOnComplete { return { - method: 'opup_bootstrap(pay)uint64' as const, - methodArgs: Array.isArray(args) ? args : [args.ptxn], ...params, + method: 'opup_bootstrap(pay)uint64' as const, + args: Array.isArray(params.args) ? params.args : [params.args.ptxn], } } /** * Constructs a no op call for the bootstrap(pay)void ABI method * - * @param args Any args for the contract call - * @param params Any additional parameters for the call - * @returns A TypedCallParams object for the call + * @param params Parameters for the call + * @returns An `AppClientMethodCallParams` object for the call */ - static bootstrap(args: MethodArgs<'bootstrap(pay)void'>, params: AppClientCallCoreParams & CoreAppCallArgs) { + static bootstrap(params: CallParams & CallOnComplete): AppClientMethodCallParams & CallOnComplete { return { - method: 'bootstrap(pay)void' as const, - methodArgs: Array.isArray(args) ? args : [args.fundMinBalReq], ...params, + method: 'bootstrap(pay)void' as const, + args: Array.isArray(params.args) ? params.args : [params.args.fundMinBalReq], } } /** * Constructs a no op call for the close(application)void ABI method * - * @param args Any args for the contract call - * @param params Any additional parameters for the call - * @returns A TypedCallParams object for the call + * @param params Parameters for the call + * @returns An `AppClientMethodCallParams` object for the call */ - static close(args: MethodArgs<'close(application)void'>, params: AppClientCallCoreParams & CoreAppCallArgs) { + static close(params: CallParams & CallOnComplete): AppClientMethodCallParams & CallOnComplete { return { - method: 'close(application)void' as const, - methodArgs: Array.isArray(args) ? args : [args.opupApp], ...params, + method: 'close(application)void' as const, + args: Array.isArray(params.args) ? params.args : [params.args.opupApp], } } /** * Constructs a no op call for the get_preconditions(byte[],uint64,application)(uint64,uint64,uint64,uint64) ABI method * - * @param args Any args for the contract call - * @param params Any additional parameters for the call - * @returns A TypedCallParams object for the call + * @param params Parameters for the call + * @returns An `AppClientMethodCallParams` object for the call */ - static getPreconditions( - args: MethodArgs<'get_preconditions(byte[],uint64,application)(uint64,uint64,uint64,uint64)'>, - params: AppClientCallCoreParams & CoreAppCallArgs, - ) { + static getPreconditions(params: CallParams & CallOnComplete): AppClientMethodCallParams & CallOnComplete { return { - method: 'get_preconditions(byte[],uint64,application)(uint64,uint64,uint64,uint64)' as const, - methodArgs: Array.isArray(args) ? args : [args.signature, args.weighting, args.opupApp], ...params, + method: 'get_preconditions(byte[],uint64,application)(uint64,uint64,uint64,uint64)' as const, + args: Array.isArray(params.args) ? params.args : [params.args.signature, params.args.weighting, params.args.opupApp], } } /** * Constructs a no op call for the vote(pay,byte[],uint64,uint8[],uint64[],application)void ABI method * - * @param args Any args for the contract call - * @param params Any additional parameters for the call - * @returns A TypedCallParams object for the call + * @param params Parameters for the call + * @returns An `AppClientMethodCallParams` object for the call */ - static vote( - args: MethodArgs<'vote(pay,byte[],uint64,uint8[],uint64[],application)void'>, - params: AppClientCallCoreParams & CoreAppCallArgs, - ) { + static vote(params: CallParams & CallOnComplete): AppClientMethodCallParams & CallOnComplete { return { - method: 'vote(pay,byte[],uint64,uint8[],uint64[],application)void' as const, - methodArgs: Array.isArray(args) - ? args - : [args.fundMinBalReq, args.signature, args.weighting, args.answerIds, args.answerWeights, args.opupApp], ...params, + method: 'vote(pay,byte[],uint64,uint8[],uint64[],application)void' as const, + args: Array.isArray(params.args) ? params.args : [params.args.fundMinBalReq, params.args.signature, params.args.weighting, params.args.answerIds, params.args.answerWeights, params.args.opupApp], } } } /** - * A client to make calls to the VotingRoundApp smart contract + * A factory to create and deploy one or more instance of the VotingRoundApp smart contract and to create one or more app clients to interact with those (or other) app instances */ -export class VotingRoundAppClient { +export class VotingRoundAppFactory { /** - * The underlying `ApplicationClient` for when you want to have more flexibility + * The underlying `AppFactory` for when you want to have more flexibility */ - public readonly appClient: ApplicationClient - - private readonly sender: SendTransactionFrom | undefined + public readonly appFactory: _AppFactory /** - * Creates a new instance of `VotingRoundAppClient` + * Creates a new instance of `VotingRoundAppFactory` * - * @param appDetails appDetails The details to identify the app to deploy - * @param algod An algod client instance + * @param params The parameters to initialise the app factory with */ - constructor( - appDetails: AppDetails, - private algod: Algodv2, - ) { - this.sender = appDetails.sender - this.appClient = algokit.getAppClient( - { - ...appDetails, - app: APP_SPEC, - }, - algod, - ) + constructor(params: Omit) { + this.appFactory = new _AppFactory({ + ...params, + appSpec: APP_SPEC, + }) } - + + /** The name of the app (from the ARC-32 / ARC-56 app spec or override). */ + public get appName() { + return this.appFactory.appName + } + + /** The ARC-56 app spec being used */ + get appSpec() { + return APP_SPEC + } + + /** A reference to the underlying `AlgorandClient` this app factory is using. */ + public get algorand(): AlgorandClientInterface { + return this.appFactory.algorand + } + /** - * Checks for decode errors on the AppCallTransactionResult and maps the return value to the specified generic type + * Returns a new `AppClient` client for an app instance of the given ID. * - * @param result The AppCallTransactionResult to be mapped - * @param returnValueFormatter An optional delegate to format the return value if required - * @returns The smart contract response with an updated return value + * Automatically populates appName, defaultSender and source maps from the factory + * if not specified in the params. + * @param params The parameters to create the app client + * @returns The `AppClient` */ - protected mapReturnValue( - result: AppCallTransactionResult, - returnValueFormatter?: (value: any) => TReturn, - ): AppCallTransactionResultOfType & TResult { - if (result.return?.decodeError) { - throw result.return.decodeError - } - const returnValue = - result.return?.returnValue !== undefined && returnValueFormatter !== undefined - ? returnValueFormatter(result.return.returnValue) - : (result.return?.returnValue as TReturn | undefined) - return { ...result, return: returnValue } as AppCallTransactionResultOfType & TResult + public getAppClientById(params: AppFactoryAppClientParams) { + return new VotingRoundAppClient(this.appFactory.getAppClientById(params)) } - + /** - * Calls the ABI method with the matching signature using an onCompletion code of NO_OP + * Returns a new `AppClient` client, resolving the app by creator address and name + * using AlgoKit app deployment semantics (i.e. looking for the app creation transaction note). * - * @param typedCallParams An object containing the method signature, args, and any other relevant parameters - * @param returnValueFormatter An optional delegate which when provided will be used to map non-undefined return values to the target type - * @returns The result of the smart contract call + * Automatically populates appName, defaultSender and source maps from the factory + * if not specified in the params. + * @param params The parameters to create the app client + * @returns The `AppClient` */ - public async call( - typedCallParams: TypedCallParams, - returnValueFormatter?: (value: any) => MethodReturn, + public async getAppClientByCreatorAndName( + params: AppFactoryResolveAppClientByCreatorAndNameParams, ) { - return this.mapReturnValue>(await this.appClient.call(typedCallParams), returnValueFormatter) + return new VotingRoundAppClient(await this.appFactory.getAppClientByCreatorAndName(params)) } /** @@ -867,326 +484,639 @@ export class VotingRoundAppClient { * @param params The arguments for the contract calls and any additional parameters for the call * @returns The deployment result */ - public deploy( - params: VotingRoundAppDeployArgs & AppClientDeployCoreParams & IncludeSchema = {}, - ): ReturnType { - const createArgs = params.createCall?.(VotingRoundAppCallFactory.create) - const deleteArgs = params.deleteCall?.(VotingRoundAppCallFactory.delete) - return this.appClient.deploy({ + public async deploy(params: VotingRoundAppDeployParams = {}) { + const result = await this.appFactory.deploy({ ...params, - deleteArgs, - createArgs, - createOnCompleteAction: createArgs?.onCompleteAction, + createParams: params.createParams?.method ? VotingRoundAppParamsFactory.create._resolveByMethod(params.createParams) : params.createParams, }) + return { result: result.result, appClient: new VotingRoundAppClient(result.appClient) } } /** - * Gets available create methods + * Get parameters to create transactions (create and deploy related calls) for the current app. A good mental model for this is that these parameters represent a deferred transaction creation. */ - public get create() { - const $this = this - return { + readonly params = { + /** + * Gets available create methods + */ + create: { /** * Creates a new instance of the VotingRoundApp smart contract using the create(string,uint8,byte[],string,uint64,uint64,uint8[],uint64,string)void ABI method. * - * @param args The arguments for the smart contract call - * @param params Any additional parameters for the call - * @returns The create result + * @param params The params for the smart contract call + * @returns The create params */ - async create( - args: MethodArgs<'create(string,uint8,byte[],string,uint64,uint64,uint8[],uint64,string)void'>, - params: AppClientCallCoreParams & AppClientCompilationParams & IncludeSchema & CoreAppCallArgs & OnCompleteNoOp = {}, - ) { - return $this.mapReturnValue< - MethodReturn<'create(string,uint8,byte[],string,uint64,uint64,uint8[],uint64,string)void'>, - AppCreateCallTransactionResult - >(await $this.appClient.create(VotingRoundAppCallFactory.create.create(args, params))) + create: (params: CallParams & AppClientCompilationParams & CreateSchema & {onComplete?: OnApplicationComplete.NoOpOC}) => { + return this.appFactory.params.create(VotingRoundAppParamsFactory.create.create(params)) }, - } + }, + + /** + * Gets available deployDelete methods + */ + deployDelete: { + /** + * Deletes an existing instance of the VotingRoundApp smart contract using a bare call. + * + * @param params The params for the bare (raw) call + * @returns The params for a deployDelete call + */ + bare: (params?: Expand) => { + return this.appFactory.params.bare.deployDelete(params) + }, + }, + } /** - * Gets available delete methods + * Create transactions for the current app */ - public get delete() { - const $this = this - return { + readonly createTransaction = { + /** + * Gets available create methods + */ + create: { /** - * Deletes an existing instance of the VotingRoundApp smart contract using a bare call. + * Creates a new instance of the VotingRoundApp smart contract using the create(string,uint8,byte[],string,uint64,uint64,uint8[],uint64,string)void ABI method. * - * @param args The arguments for the bare call - * @returns The delete result + * @param params The params for the smart contract call + * @returns The create transaction */ - async bare(args: BareCallArgs & AppClientCallCoreParams & CoreAppCallArgs = {}) { - return $this.mapReturnValue(await $this.appClient.delete(args)) + create: (params: CallParams & AppClientCompilationParams & CreateSchema & {onComplete?: OnApplicationComplete.NoOpOC}) => { + return this.appFactory.createTransaction.create(VotingRoundAppParamsFactory.create.create(params)) }, - } + }, + } /** - * Makes a clear_state call to an existing instance of the VotingRoundApp smart contract. - * - * @param args The arguments for the bare call - * @returns The clear_state result + * Send calls to the current app */ - public clearState(args: BareCallArgs & AppClientCallCoreParams & CoreAppCallArgs = {}) { - return this.appClient.clearState(args) + readonly send = { + /** + * Gets available create methods + */ + create: { + /** + * Creates a new instance of the VotingRoundApp smart contract using an ABI method call using the create(string,uint8,byte[],string,uint64,uint64,uint8[],uint64,string)void ABI method. + * + * @param params The params for the smart contract call + * @returns The create result + */ + create: async (params: CallParams & AppClientCompilationParams & CreateSchema & SendParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + const result = await this.appFactory.send.create(VotingRoundAppParamsFactory.create.create(params)) + return { result: { ...result.result, return: result.result.return as undefined | VotingRoundAppReturns['create(string,uint8,byte[],string,uint64,uint64,uint8[],uint64,string)void'] }, appClient: new VotingRoundAppClient(result.appClient) } + }, + }, + } +} +/** + * A client to make calls to the VotingRoundApp smart contract + */ +export class VotingRoundAppClient { + /** + * The underlying `AppClient` for when you want to have more flexibility + */ + public readonly appClient: _AppClient + /** - * Calls the opup_bootstrap(pay)uint64 ABI method. + * Creates a new instance of `VotingRoundAppClient` * - * initialize opup with bootstrap to create a target app + * @param appClient An `AppClient` instance which has been created with the VotingRoundApp app spec + */ + constructor(appClient: _AppClient) + /** + * Creates a new instance of `VotingRoundAppClient` * - * @param args The arguments for the contract call - * @param params Any additional parameters for the call - * @returns The result of the call + * @param params The parameters to initialise the app client with */ - public opupBootstrap(args: MethodArgs<'opup_bootstrap(pay)uint64'>, params: AppClientCallCoreParams & CoreAppCallArgs = {}) { - return this.call(VotingRoundAppCallFactory.opupBootstrap(args, params)) + constructor(params: Omit) + constructor(appClientOrParams: _AppClient | Omit) { + this.appClient = appClientOrParams instanceof _AppClient ? appClientOrParams : new _AppClient({ + ...appClientOrParams, + appSpec: APP_SPEC, + }) } - + /** - * Calls the bootstrap(pay)void ABI method. + * Checks for decode errors on the given return value and maps the return value to the return type for the given method + * @returns The typed return value or undefined if there was no value + */ + decodeReturnValue(method: TSignature, returnValue: ABIReturn | undefined) { + return returnValue !== undefined ? getArc56ReturnValue>(returnValue, this.appClient.getABIMethod(method), APP_SPEC.structs) : undefined + } + + /** + * Returns a new `VotingRoundAppClient` client, resolving the app by creator address and name + * using AlgoKit app deployment semantics (i.e. looking for the app creation transaction note). + * @param params The parameters to create the app client + */ + public static async fromCreatorAndName(params: Omit): Promise { + return new VotingRoundAppClient(await _AppClient.fromCreatorAndName({...params, appSpec: APP_SPEC})) + } + + /** + * Returns an `VotingRoundAppClient` instance for the current network based on + * pre-determined network-specific app IDs specified in the ARC-56 app spec. * - * @param args The arguments for the contract call - * @param params Any additional parameters for the call - * @returns The result of the call + * If no IDs are in the app spec or the network isn't recognised, an error is thrown. + * @param params The parameters to create the app client */ - public bootstrap(args: MethodArgs<'bootstrap(pay)void'>, params: AppClientCallCoreParams & CoreAppCallArgs = {}) { - return this.call(VotingRoundAppCallFactory.bootstrap(args, params)) + static async fromNetwork( + params: Omit + ): Promise { + return new VotingRoundAppClient(await _AppClient.fromNetwork({...params, appSpec: APP_SPEC})) + } + + /** The ID of the app instance this client is linked to. */ + public get appId() { + return this.appClient.appId + } + + /** The app address of the app instance this client is linked to. */ + public get appAddress() { + return this.appClient.appAddress + } + + /** The name of the app. */ + public get appName() { + return this.appClient.appName + } + + /** The ARC-56 app spec being used */ + public get appSpec() { + return this.appClient.appSpec + } + + /** A reference to the underlying `AlgorandClient` this app client is using. */ + public get algorand(): AlgorandClientInterface { + return this.appClient.algorand } /** - * Calls the close(application)void ABI method. - * - * @param args The arguments for the contract call - * @param params Any additional parameters for the call - * @returns The result of the call + * Get parameters to create transactions for the current app. A good mental model for this is that these parameters represent a deferred transaction creation. */ - public close(args: MethodArgs<'close(application)void'>, params: AppClientCallCoreParams & CoreAppCallArgs = {}) { - return this.call(VotingRoundAppCallFactory.close(args, params)) + readonly params = { + /** + * Gets available delete methods + */ + delete: { + /** + * Deletes an existing instance of the VotingRoundApp smart contract using a bare call. + * + * @param params The params for the bare (raw) call + * @returns The delete result + */ + bare: (params?: Expand) => { + return this.appClient.params.bare.delete(params) + }, + }, + + /** + * Makes a clear_state call to an existing instance of the VotingRoundApp smart contract. + * + * @param params The params for the bare (raw) call + * @returns The clearState result + */ + clearState: (params?: Expand) => { + return this.appClient.params.bare.clearState(params) + }, + + /** + * Makes a call to the VotingRoundApp smart contract using the `opup_bootstrap(pay)uint64` ABI method. + * + * initialize opup with bootstrap to create a target app + * + * @param params The params for the smart contract call + * @returns The call params + */ + opupBootstrap: (params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + return this.appClient.params.call(VotingRoundAppParamsFactory.opupBootstrap(params)) + }, + + /** + * Makes a call to the VotingRoundApp smart contract using the `bootstrap(pay)void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call params + */ + bootstrap: (params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + return this.appClient.params.call(VotingRoundAppParamsFactory.bootstrap(params)) + }, + + /** + * Makes a call to the VotingRoundApp smart contract using the `close(application)void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call params + */ + close: (params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC} = {args: [undefined]}) => { + return this.appClient.params.call(VotingRoundAppParamsFactory.close(params)) + }, + + /** + * Makes a call to the VotingRoundApp smart contract using the `get_preconditions(byte[],uint64,application)(uint64,uint64,uint64,uint64)` ABI method. + * + * This method is a readonly method; calling it with onComplete of NoOp will result in a simulated transaction rather than a real transaction. + * + * @param params The params for the smart contract call + * @returns The call params + */ + getPreconditions: (params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + return this.appClient.params.call(VotingRoundAppParamsFactory.getPreconditions(params)) + }, + + /** + * Makes a call to the VotingRoundApp smart contract using the `vote(pay,byte[],uint64,uint8[],uint64[],application)void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call params + */ + vote: (params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + return this.appClient.params.call(VotingRoundAppParamsFactory.vote(params)) + }, + } /** - * Calls the get_preconditions(byte[],uint64,application)(uint64,uint64,uint64,uint64) ABI method. - * - * @param args The arguments for the contract call - * @param params Any additional parameters for the call - * @returns The result of the call + * Create transactions for the current app */ - public getPreconditions( - args: MethodArgs<'get_preconditions(byte[],uint64,application)(uint64,uint64,uint64,uint64)'>, - params: AppClientCallCoreParams & CoreAppCallArgs = {}, - ) { - return this.call(VotingRoundAppCallFactory.getPreconditions(args, params), VotingPreconditions) + readonly createTransaction = { + /** + * Gets available delete methods + */ + delete: { + /** + * Deletes an existing instance of the VotingRoundApp smart contract using a bare call. + * + * @param params The params for the bare (raw) call + * @returns The delete result + */ + bare: (params?: Expand) => { + return this.appClient.createTransaction.bare.delete(params) + }, + }, + + /** + * Makes a clear_state call to an existing instance of the VotingRoundApp smart contract. + * + * @param params The params for the bare (raw) call + * @returns The clearState result + */ + clearState: (params?: Expand) => { + return this.appClient.createTransaction.bare.clearState(params) + }, + + /** + * Makes a call to the VotingRoundApp smart contract using the `opup_bootstrap(pay)uint64` ABI method. + * + * initialize opup with bootstrap to create a target app + * + * @param params The params for the smart contract call + * @returns The call transaction + */ + opupBootstrap: (params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + return this.appClient.createTransaction.call(VotingRoundAppParamsFactory.opupBootstrap(params)) + }, + + /** + * Makes a call to the VotingRoundApp smart contract using the `bootstrap(pay)void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call transaction + */ + bootstrap: (params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + return this.appClient.createTransaction.call(VotingRoundAppParamsFactory.bootstrap(params)) + }, + + /** + * Makes a call to the VotingRoundApp smart contract using the `close(application)void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call transaction + */ + close: (params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC} = {args: [undefined]}) => { + return this.appClient.createTransaction.call(VotingRoundAppParamsFactory.close(params)) + }, + + /** + * Makes a call to the VotingRoundApp smart contract using the `get_preconditions(byte[],uint64,application)(uint64,uint64,uint64,uint64)` ABI method. + * + * This method is a readonly method; calling it with onComplete of NoOp will result in a simulated transaction rather than a real transaction. + * + * @param params The params for the smart contract call + * @returns The call transaction + */ + getPreconditions: (params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + return this.appClient.createTransaction.call(VotingRoundAppParamsFactory.getPreconditions(params)) + }, + + /** + * Makes a call to the VotingRoundApp smart contract using the `vote(pay,byte[],uint64,uint8[],uint64[],application)void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call transaction + */ + vote: (params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + return this.appClient.createTransaction.call(VotingRoundAppParamsFactory.vote(params)) + }, + } /** - * Calls the vote(pay,byte[],uint64,uint8[],uint64[],application)void ABI method. - * - * @param args The arguments for the contract call - * @param params Any additional parameters for the call - * @returns The result of the call + * Send calls to the current app */ - public vote( - args: MethodArgs<'vote(pay,byte[],uint64,uint8[],uint64[],application)void'>, - params: AppClientCallCoreParams & CoreAppCallArgs = {}, - ) { - return this.call(VotingRoundAppCallFactory.vote(args, params)) + readonly send = { + /** + * Gets available delete methods + */ + delete: { + /** + * Deletes an existing instance of the VotingRoundApp smart contract using a bare call. + * + * @param params The params for the bare (raw) call + * @returns The delete result + */ + bare: (params?: Expand) => { + return this.appClient.send.bare.delete(params) + }, + }, + + /** + * Makes a clear_state call to an existing instance of the VotingRoundApp smart contract. + * + * @param params The params for the bare (raw) call + * @returns The clearState result + */ + clearState: (params?: Expand) => { + return this.appClient.send.bare.clearState(params) + }, + + /** + * Makes a call to the VotingRoundApp smart contract using the `opup_bootstrap(pay)uint64` ABI method. + * + * initialize opup with bootstrap to create a target app + * + * @param params The params for the smart contract call + * @returns The call result + */ + opupBootstrap: async (params: CallParams & SendParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + const result = await this.appClient.send.call(VotingRoundAppParamsFactory.opupBootstrap(params)) + return {...result, return: result.return as undefined | VotingRoundAppReturns['opup_bootstrap(pay)uint64']} + }, + + /** + * Makes a call to the VotingRoundApp smart contract using the `bootstrap(pay)void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call result + */ + bootstrap: async (params: CallParams & SendParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + const result = await this.appClient.send.call(VotingRoundAppParamsFactory.bootstrap(params)) + return {...result, return: result.return as undefined | VotingRoundAppReturns['bootstrap(pay)void']} + }, + + /** + * Makes a call to the VotingRoundApp smart contract using the `close(application)void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call result + */ + close: async (params: CallParams & SendParams & {onComplete?: OnApplicationComplete.NoOpOC} = {args: [undefined]}) => { + const result = await this.appClient.send.call(VotingRoundAppParamsFactory.close(params)) + return {...result, return: result.return as undefined | VotingRoundAppReturns['close(application)void']} + }, + + /** + * Makes a call to the VotingRoundApp smart contract using the `get_preconditions(byte[],uint64,application)(uint64,uint64,uint64,uint64)` ABI method. + * + * This method is a readonly method; calling it with onComplete of NoOp will result in a simulated transaction rather than a real transaction. + * + * @param params The params for the smart contract call + * @returns The call result + */ + getPreconditions: async (params: CallParams & SendParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + const result = await this.appClient.send.call(VotingRoundAppParamsFactory.getPreconditions(params)) + return {...result, return: result.return as undefined | VotingRoundAppReturns['get_preconditions(byte[],uint64,application)(uint64,uint64,uint64,uint64)']} + }, + + /** + * Makes a call to the VotingRoundApp smart contract using the `vote(pay,byte[],uint64,uint8[],uint64[],application)void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call result + */ + vote: async (params: CallParams & SendParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + const result = await this.appClient.send.call(VotingRoundAppParamsFactory.vote(params)) + return {...result, return: result.return as undefined | VotingRoundAppReturns['vote(pay,byte[],uint64,uint8[],uint64[],application)void']} + }, + } /** - * Extracts a binary state value out of an AppState dictionary + * Clone this app client with different params * - * @param state The state dictionary containing the state value - * @param key The key of the state value - * @returns A BinaryState instance containing the state value, or undefined if the key was not found + * @param params The params to use for the the cloned app client. Omit a param to keep the original value. Set a param to override the original value. Setting to undefined will clear the original value. + * @returns A new app client with the altered params */ - private static getBinaryState(state: AppState, key: string): BinaryState | undefined { - const value = state[key] - if (!value) return undefined - if (!('valueRaw' in value)) throw new Error(`Failed to parse state value for ${key}; received an int when expected a byte array`) - return { - asString(): string { - return value.value - }, - asByteArray(): Uint8Array { - return value.valueRaw - }, - } + public clone(params: CloneAppClientParams) { + return new VotingRoundAppClient(this.appClient.clone(params)) } /** - * Extracts a integer state value out of an AppState dictionary + * Makes a readonly (simulated) call to the VotingRoundApp smart contract using the `get_preconditions(byte[],uint64,application)(uint64,uint64,uint64,uint64)` ABI method. + * + * This method is a readonly method; calling it with onComplete of NoOp will result in a simulated transaction rather than a real transaction. * - * @param state The state dictionary containing the state value - * @param key The key of the state value - * @returns An IntegerState instance containing the state value, or undefined if the key was not found + * @param params The params for the smart contract call + * @returns The call result */ - private static getIntegerState(state: AppState, key: string): IntegerState | undefined { - const value = state[key] - if (!value) return undefined - if ('valueRaw' in value) throw new Error(`Failed to parse state value for ${key}; received a byte array when expected a number`) - return { - asBigInt() { - return typeof value.value === 'bigint' ? value.value : BigInt(value.value) - }, - asNumber(): number { - return typeof value.value === 'bigint' ? Number(value.value) : value.value - }, - } + async getPreconditions(params: CallParams) { + const result = await this.appClient.send.call(VotingRoundAppParamsFactory.getPreconditions(params)) + return result.return as VotingRoundAppReturns['get_preconditions(byte[],uint64,application)(uint64,uint64,uint64,uint64)'] } /** - * Returns the smart contract's global state wrapped in a strongly typed accessor with options to format the stored value + * Methods to access state for the current VotingRoundApp app */ - public async getGlobalState(): Promise { - const state = await this.appClient.getGlobalState() - return { - get closeTime() { - return VotingRoundAppClient.getIntegerState(state, 'close_time') - }, - get endTime() { - return VotingRoundAppClient.getIntegerState(state, 'end_time') - }, - get isBootstrapped() { - return VotingRoundAppClient.getIntegerState(state, 'is_bootstrapped') - }, - get metadataIpfsCid() { - return VotingRoundAppClient.getBinaryState(state, 'metadata_ipfs_cid') - }, - get nftAssetId() { - return VotingRoundAppClient.getIntegerState(state, 'nft_asset_id') - }, - get nftImageUrl() { - return VotingRoundAppClient.getBinaryState(state, 'nft_image_url') - }, - get optionCounts() { - return VotingRoundAppClient.getBinaryState(state, 'option_counts') - }, - get ouaid() { - return VotingRoundAppClient.getIntegerState(state, 'ouaid') - }, - get quorum() { - return VotingRoundAppClient.getIntegerState(state, 'quorum') - }, - get snapshotPublicKey() { - return VotingRoundAppClient.getBinaryState(state, 'snapshot_public_key') - }, - get startTime() { - return VotingRoundAppClient.getIntegerState(state, 'start_time') - }, - get totalOptions() { - return VotingRoundAppClient.getIntegerState(state, 'total_options') - }, - get voteId() { - return VotingRoundAppClient.getBinaryState(state, 'vote_id') - }, - get voteType() { - return VotingRoundAppClient.getIntegerState(state, 'vote_type') - }, - get voterCount() { - return VotingRoundAppClient.getIntegerState(state, 'voter_count') + state = { + /** + * Methods to access global state for the current VotingRoundApp app + */ + global: { + /** + * Get all current keyed values from global state + */ + getAll: async (): Promise>> => { + const result = await this.appClient.state.global.getAll() + return { + closeTime: result.close_time, + endTime: result.end_time, + isBootstrapped: result.is_bootstrapped, + metadataIpfsCid: new BinaryStateValue(result.metadata_ipfs_cid), + nftAssetId: result.nft_asset_id, + nftImageUrl: new BinaryStateValue(result.nft_image_url), + optionCounts: new BinaryStateValue(result.option_counts), + opupAppId: result.opup_app_id, + quorum: result.quorum, + snapshotPublicKey: new BinaryStateValue(result.snapshot_public_key), + startTime: result.start_time, + totalOptions: result.total_options, + voteId: new BinaryStateValue(result.vote_id), + voteType: result.vote_type, + voterCount: result.voter_count, + } }, - } + /** + * Get the current value of the close_time key in global state + */ + closeTime: async (): Promise => { return (await this.appClient.state.global.getValue("closeTime")) as bigint | undefined }, + /** + * Get the current value of the end_time key in global state + */ + endTime: async (): Promise => { return (await this.appClient.state.global.getValue("endTime")) as bigint | undefined }, + /** + * Get the current value of the is_bootstrapped key in global state + */ + isBootstrapped: async (): Promise => { return (await this.appClient.state.global.getValue("isBootstrapped")) as bigint | undefined }, + /** + * Get the current value of the metadata_ipfs_cid key in global state + */ + metadataIpfsCid: async (): Promise => { return new BinaryStateValue((await this.appClient.state.global.getValue("metadataIpfsCid")) as Uint8Array | undefined) }, + /** + * Get the current value of the nft_asset_id key in global state + */ + nftAssetId: async (): Promise => { return (await this.appClient.state.global.getValue("nftAssetId")) as bigint | undefined }, + /** + * Get the current value of the nft_image_url key in global state + */ + nftImageUrl: async (): Promise => { return new BinaryStateValue((await this.appClient.state.global.getValue("nftImageUrl")) as Uint8Array | undefined) }, + /** + * Get the current value of the option_counts key in global state + */ + optionCounts: async (): Promise => { return new BinaryStateValue((await this.appClient.state.global.getValue("optionCounts")) as Uint8Array | undefined) }, + /** + * Get the current value of the opup_app_id key in global state + */ + opupAppId: async (): Promise => { return (await this.appClient.state.global.getValue("opupAppId")) as bigint | undefined }, + /** + * Get the current value of the quorum key in global state + */ + quorum: async (): Promise => { return (await this.appClient.state.global.getValue("quorum")) as bigint | undefined }, + /** + * Get the current value of the snapshot_public_key key in global state + */ + snapshotPublicKey: async (): Promise => { return new BinaryStateValue((await this.appClient.state.global.getValue("snapshotPublicKey")) as Uint8Array | undefined) }, + /** + * Get the current value of the start_time key in global state + */ + startTime: async (): Promise => { return (await this.appClient.state.global.getValue("startTime")) as bigint | undefined }, + /** + * Get the current value of the total_options key in global state + */ + totalOptions: async (): Promise => { return (await this.appClient.state.global.getValue("totalOptions")) as bigint | undefined }, + /** + * Get the current value of the vote_id key in global state + */ + voteId: async (): Promise => { return new BinaryStateValue((await this.appClient.state.global.getValue("voteId")) as Uint8Array | undefined) }, + /** + * Get the current value of the vote_type key in global state + */ + voteType: async (): Promise => { return (await this.appClient.state.global.getValue("voteType")) as bigint | undefined }, + /** + * Get the current value of the voter_count key in global state + */ + voterCount: async (): Promise => { return (await this.appClient.state.global.getValue("voterCount")) as bigint | undefined }, + }, } - public compose(): VotingRoundAppComposer { + public newGroup(): VotingRoundAppComposer { const client = this - const atc = new AtomicTransactionComposer() - let promiseChain: Promise = Promise.resolve() - const resultMappers: Array any)> = [] + const composer = this.algorand.newGroup() + let promiseChain:Promise = Promise.resolve() + const resultMappers: Array any)> = [] return { - opupBootstrap(args: MethodArgs<'opup_bootstrap(pay)uint64'>, params?: AppClientComposeCallCoreParams & CoreAppCallArgs) { - promiseChain = promiseChain.then(() => - client.opupBootstrap(args, { ...params, sendParams: { ...params?.sendParams, skipSending: true, atc } }), - ) - resultMappers.push(undefined) + /** + * Add a opup_bootstrap(pay)uint64 method call against the VotingRoundApp contract + */ + opupBootstrap(params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) { + promiseChain = promiseChain.then(async () => composer.addAppCallMethodCall(await client.params.opupBootstrap(params))) + resultMappers.push((v) => client.decodeReturnValue('opup_bootstrap(pay)uint64', v)) return this }, - bootstrap(args: MethodArgs<'bootstrap(pay)void'>, params?: AppClientComposeCallCoreParams & CoreAppCallArgs) { - promiseChain = promiseChain.then(() => - client.bootstrap(args, { ...params, sendParams: { ...params?.sendParams, skipSending: true, atc } }), - ) + /** + * Add a bootstrap(pay)void method call against the VotingRoundApp contract + */ + bootstrap(params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) { + promiseChain = promiseChain.then(async () => composer.addAppCallMethodCall(await client.params.bootstrap(params))) resultMappers.push(undefined) return this }, - close(args: MethodArgs<'close(application)void'>, params?: AppClientComposeCallCoreParams & CoreAppCallArgs) { - promiseChain = promiseChain.then(() => - client.close(args, { ...params, sendParams: { ...params?.sendParams, skipSending: true, atc } }), - ) + /** + * Add a close(application)void method call against the VotingRoundApp contract + */ + close(params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) { + promiseChain = promiseChain.then(async () => composer.addAppCallMethodCall(await client.params.close(params))) resultMappers.push(undefined) return this }, - getPreconditions( - args: MethodArgs<'get_preconditions(byte[],uint64,application)(uint64,uint64,uint64,uint64)'>, - params?: AppClientComposeCallCoreParams & CoreAppCallArgs, - ) { - promiseChain = promiseChain.then(() => - client.getPreconditions(args, { ...params, sendParams: { ...params?.sendParams, skipSending: true, atc } }), - ) - resultMappers.push(VotingPreconditions) + /** + * Add a get_preconditions(byte[],uint64,application)(uint64,uint64,uint64,uint64) method call against the VotingRoundApp contract + */ + getPreconditions(params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) { + promiseChain = promiseChain.then(async () => composer.addAppCallMethodCall(await client.params.getPreconditions(params))) + resultMappers.push((v) => client.decodeReturnValue('get_preconditions(byte[],uint64,application)(uint64,uint64,uint64,uint64)', v)) return this }, - vote( - args: MethodArgs<'vote(pay,byte[],uint64,uint8[],uint64[],application)void'>, - params?: AppClientComposeCallCoreParams & CoreAppCallArgs, - ) { - promiseChain = promiseChain.then(() => - client.vote(args, { ...params, sendParams: { ...params?.sendParams, skipSending: true, atc } }), - ) + /** + * Add a vote(pay,byte[],uint64,uint8[],uint64[],application)void method call against the VotingRoundApp contract + */ + vote(params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) { + promiseChain = promiseChain.then(async () => composer.addAppCallMethodCall(await client.params.vote(params))) resultMappers.push(undefined) return this }, get delete() { - const $this = this return { - bare(args?: BareCallArgs & AppClientComposeCallCoreParams & CoreAppCallArgs) { - promiseChain = promiseChain.then(() => - client.delete.bare({ ...args, sendParams: { ...args?.sendParams, skipSending: true, atc } }), - ) - resultMappers.push(undefined) - return $this + bare: (params?: AppClientBareCallParams ) => { + promiseChain = promiseChain.then(() => composer.addAppDelete(client.params.delete.bare(params))) + return this }, } }, - clearState(args?: BareCallArgs & AppClientComposeCallCoreParams & CoreAppCallArgs) { - promiseChain = promiseChain.then(() => client.clearState({ ...args, sendParams: { ...args?.sendParams, skipSending: true, atc } })) - resultMappers.push(undefined) + /** + * Add a clear state call to the VotingRoundApp contract + */ + clearState(params: AppClientBareCallParams) { + promiseChain = promiseChain.then(() => composer.addAppCall(client.params.clearState(params))) return this }, - addTransaction( - txn: TransactionWithSigner | TransactionToSign | Transaction | Promise, - defaultSender?: SendTransactionFrom, - ) { - promiseChain = promiseChain.then(async () => - atc.addTransaction(await algokit.getTransactionWithSigner(txn, defaultSender ?? client.sender)), - ) + addTransaction(txn: Transaction, signer?: TransactionSigner) { + promiseChain = promiseChain.then(() => composer.addTransaction(txn, signer)) return this }, - async atc() { + async composer() { await promiseChain - return atc + return composer }, async simulate(options?: SimulateOptions) { await promiseChain - const result = await atc.simulate(client.algod, new modelsv2.SimulateRequest({ txnGroups: [], ...options })) + const result = await composer.simulate(options) return { ...result, - returns: result.methodResults?.map((val, i) => - resultMappers[i] !== undefined ? resultMappers[i]!(val.returnValue) : val.returnValue, - ), + returns: result.returns?.map((val, i) => resultMappers[i] !== undefined ? resultMappers[i]!(val) : val.returnValue) } }, - async execute(sendParams?: AppClientComposeExecuteParams) { + async send(params?: SendParams) { await promiseChain - const result = await algokit.sendAtomicTransactionComposer({ atc, sendParams }, client.algod) + const result = await composer.send(params) return { ...result, - returns: result.returns?.map((val, i) => (resultMappers[i] !== undefined ? resultMappers[i]!(val.returnValue) : val.returnValue)), + returns: result.returns?.map((val, i) => resultMappers[i] !== undefined ? resultMappers[i]!(val) : val.returnValue) } - }, + } } as unknown as VotingRoundAppComposer } } @@ -1200,10 +1130,7 @@ export type VotingRoundAppComposer = { * @param params Any additional parameters for the call * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions */ - opupBootstrap( - args: MethodArgs<'opup_bootstrap(pay)uint64'>, - params?: AppClientComposeCallCoreParams & CoreAppCallArgs, - ): VotingRoundAppComposer<[...TReturns, MethodReturn<'opup_bootstrap(pay)uint64'>]> + opupBootstrap(params?: CallParams): VotingRoundAppComposer<[...TReturns, VotingRoundAppReturns['opup_bootstrap(pay)uint64'] | undefined]> /** * Calls the bootstrap(pay)void ABI method. @@ -1212,10 +1139,7 @@ export type VotingRoundAppComposer = { * @param params Any additional parameters for the call * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions */ - bootstrap( - args: MethodArgs<'bootstrap(pay)void'>, - params?: AppClientComposeCallCoreParams & CoreAppCallArgs, - ): VotingRoundAppComposer<[...TReturns, MethodReturn<'bootstrap(pay)void'>]> + bootstrap(params?: CallParams): VotingRoundAppComposer<[...TReturns, VotingRoundAppReturns['bootstrap(pay)void'] | undefined]> /** * Calls the close(application)void ABI method. @@ -1224,10 +1148,7 @@ export type VotingRoundAppComposer = { * @param params Any additional parameters for the call * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions */ - close( - args: MethodArgs<'close(application)void'>, - params?: AppClientComposeCallCoreParams & CoreAppCallArgs, - ): VotingRoundAppComposer<[...TReturns, MethodReturn<'close(application)void'>]> + close(params?: CallParams): VotingRoundAppComposer<[...TReturns, VotingRoundAppReturns['close(application)void'] | undefined]> /** * Calls the get_preconditions(byte[],uint64,application)(uint64,uint64,uint64,uint64) ABI method. @@ -1236,10 +1157,7 @@ export type VotingRoundAppComposer = { * @param params Any additional parameters for the call * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions */ - getPreconditions( - args: MethodArgs<'get_preconditions(byte[],uint64,application)(uint64,uint64,uint64,uint64)'>, - params?: AppClientComposeCallCoreParams & CoreAppCallArgs, - ): VotingRoundAppComposer<[...TReturns, MethodReturn<'get_preconditions(byte[],uint64,application)(uint64,uint64,uint64,uint64)'>]> + getPreconditions(params?: CallParams): VotingRoundAppComposer<[...TReturns, VotingRoundAppReturns['get_preconditions(byte[],uint64,application)(uint64,uint64,uint64,uint64)'] | undefined]> /** * Calls the vote(pay,byte[],uint64,uint8[],uint64[],application)void ABI method. @@ -1248,10 +1166,7 @@ export type VotingRoundAppComposer = { * @param params Any additional parameters for the call * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions */ - vote( - args: MethodArgs<'vote(pay,byte[],uint64,uint8[],uint64[],application)void'>, - params?: AppClientComposeCallCoreParams & CoreAppCallArgs, - ): VotingRoundAppComposer<[...TReturns, MethodReturn<'vote(pay,byte[],uint64,uint8[],uint64[],application)void'>]> + vote(params?: CallParams): VotingRoundAppComposer<[...TReturns, VotingRoundAppReturns['vote(pay,byte[],uint64,uint8[],uint64[],application)void'] | undefined]> /** * Gets available delete methods @@ -1263,7 +1178,7 @@ export type VotingRoundAppComposer = { * @param args The arguments for the bare call * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions */ - bare(args?: BareCallArgs & AppClientComposeCallCoreParams & CoreAppCallArgs): VotingRoundAppComposer<[...TReturns, undefined]> + bare(params?: AppClientBareCallParams ): VotingRoundAppComposer<[...TReturns, undefined]> } /** @@ -1272,40 +1187,29 @@ export type VotingRoundAppComposer = { * @param args The arguments for the bare call * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions */ - clearState(args?: BareCallArgs & AppClientComposeCallCoreParams & CoreAppCallArgs): VotingRoundAppComposer<[...TReturns, undefined]> + clearState(params?: AppClientBareCallParams): VotingRoundAppComposer<[...TReturns, undefined]> /** * Adds a transaction to the composer * - * @param txn One of: A TransactionWithSigner object (returned as is), a TransactionToSign object (signer is obtained from the signer property), a Transaction object (signer is extracted from the defaultSender parameter), an async SendTransactionResult returned by one of algokit utils helpers (signer is obtained from the defaultSender parameter) - * @param defaultSender The default sender to be used to obtain a signer where the object provided to the transaction parameter does not include a signer. + * @param txn A transaction to add to the transaction group + * @param signer The optional signer to use when signing this transaction. */ - addTransaction( - txn: TransactionWithSigner | TransactionToSign | Transaction | Promise, - defaultSender?: SendTransactionFrom, - ): VotingRoundAppComposer + addTransaction(txn: Transaction, signer?: TransactionSigner): VotingRoundAppComposer /** * Returns the underlying AtomicTransactionComposer instance */ - atc(): Promise + composer(): TransactionComposer /** * Simulates the transaction group and returns the result */ - simulate(options?: SimulateOptions): Promise> + simulate(options?: SimulateOptions): Promise & { simulateResponse: SimulateResponse }> /** - * Executes the transaction group and returns the results + * Sends the transaction group to the network and returns the results */ - execute(sendParams?: AppClientComposeExecuteParams): Promise> + send(params?: SendParams): Promise> } -export type SimulateOptions = Omit[0], 'txnGroups'> -export type VotingRoundAppComposerSimulateResult = { +export type VotingRoundAppComposerResults = Expand = { - returns: TReturns - groupId: string - txIds: string[] - transactions: Transaction[] -} +}> + diff --git a/package-lock.json b/package-lock.json index 9c209ec..2992dd7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,9 +15,10 @@ "js-sha512": "^0.9.0" }, "devDependencies": { + "@algorandfoundation/algokit-client-generator": "^4.0.2", "@commitlint/cli": "^19.2.1", "@commitlint/config-conventional": "^19.1.0", - "@makerx/eslint-config": "^3.1.1", + "@eslint/js": "^9.16.0", "@makerx/prettier-config": "^2.0.1", "@prisma/client": "^5.15.1", "@rollup/plugin-typescript": "^11.1.6", @@ -27,7 +28,7 @@ "cpy-cli": "^5.0.0", "cross-env": "^7.0.3", "dotenv-cli": "^7.4.1", - "eslint": "8.57.0", + "eslint-config-prettier": "^9.1.0", "npm-run-all": "^4.1.5", "prettier": "3.2.5", "prisma": "^5.15.1", @@ -39,14 +40,15 @@ "typedoc": "^0.25.4", "typedoc-plugin-markdown": "^3.17.1", "typescript": "^5.4.3", + "typescript-eslint": "^8.16.0", "vitest": "^2.1.4" }, "engines": { "node": ">=18.0" }, "peerDependencies": { - "@algorandfoundation/algokit-utils": "^6.1.0", - "algosdk": "^2.7.0" + "@algorandfoundation/algokit-utils": "^7.0.0", + "algosdk": ">=2.9.0 <3.0" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -54,23 +56,47 @@ "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", "dev": true, + "peer": true, "engines": { "node": ">=0.10.0" } }, + "node_modules/@algorandfoundation/algokit-client-generator": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@algorandfoundation/algokit-client-generator/-/algokit-client-generator-4.0.2.tgz", + "integrity": "sha512-c57qdsEMjJ6UMpEc2/IzZ/aPlGJ9olO1s+HTzsmG/FHPge/mASIZypxBncNQo/fdL1XhkafMje/1kwGfDd6xeg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.2", + "change-case": "^5.4.4", + "commander": "^11.1.0", + "jsonschema": "^1.4.1" + }, + "bin": { + "algokit-client-generator": "bin/cli.mjs", + "algokitgen": "bin/cli.mjs" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "@algorandfoundation/algokit-utils": "^7.0.0 || ^8.0.0", + "algosdk": "^2.9.0 || ^3.0.0" + } + }, "node_modules/@algorandfoundation/algokit-utils": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@algorandfoundation/algokit-utils/-/algokit-utils-6.1.0.tgz", - "integrity": "sha512-rrakN+k5/SPd0RPZHLbpN9H+QQVud/NpbaVUCWVkBflHYvsM0sGaXUNNuHucqttR7uhvJwVfFnRe81aHyukMAA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@algorandfoundation/algokit-utils/-/algokit-utils-7.0.0.tgz", + "integrity": "sha512-L+8ykFgQVEs802yozldp+QFwW5z0sFXxSeHFYztZIVAACwVK4C/z5DnIF/AA+g8L98sv3VPkOvjjvPSya5szZQ==", "peer": true, "dependencies": { "buffer": "^6.0.3" }, "engines": { - "node": ">=18.0" + "node": ">=20.0" }, "peerDependencies": { - "algosdk": "^2.7.0" + "algosdk": ">=2.9.0 <3.0" } }, "node_modules/@ampproject/remapping": { @@ -1225,6 +1251,7 @@ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, + "peer": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -1244,12 +1271,12 @@ } }, "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "version": "9.16.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.16.0.tgz", + "integrity": "sha512-tw2HxzQkrbeuvyj1tG2Yqq+0H9wGoI2IMk4EOsQeX+vmd75FtJAzf+gTA69WF+baUKRYQ3x2kbLE08js5OsTVg==", "dev": true, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@humanwhocodes/config-array": { @@ -1257,6 +1284,7 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, + "peer": true, "dependencies": { "@humanwhocodes/object-schema": "^2.0.2", "debug": "^4.3.1", @@ -1271,6 +1299,7 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, + "peer": true, "engines": { "node": ">=12.22" }, @@ -1283,7 +1312,8 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", - "dev": true + "dev": true, + "peer": true }, "node_modules/@isaacs/cliui": { "version": "8.0.2", @@ -1448,18 +1478,6 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, - "node_modules/@makerx/eslint-config": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@makerx/eslint-config/-/eslint-config-3.1.1.tgz", - "integrity": "sha512-c0rKUDeqIW8hjkm5py6CCPswhjU2xhsO6ML3gWWygKlXg40QHHViMVMy3TBrsMfCoEOn60h7pleH6aeVN5D+Gw==", - "dev": true, - "peerDependencies": { - "@typescript-eslint/eslint-plugin": "*", - "@typescript-eslint/parser": "*", - "eslint-config-prettier": "*", - "eslint-plugin-prettier": "*" - } - }, "node_modules/@makerx/prettier-config": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@makerx/prettier-config/-/prettier-config-2.0.1.tgz", @@ -1655,27 +1673,6 @@ "node": ">=14" } }, - "node_modules/@pkgr/utils": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.2.tgz", - "integrity": "sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw==", - "dev": true, - "peer": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "fast-glob": "^3.3.0", - "is-glob": "^4.0.3", - "open": "^9.1.0", - "picocolors": "^1.0.0", - "tslib": "^2.6.0" - }, - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, "node_modules/@pnpm/config.env-replace": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", @@ -2459,13 +2456,6 @@ "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "dev": true }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, - "peer": true - }, "node_modules/@types/node": { "version": "20.9.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.9.0.tgz", @@ -2481,13 +2471,6 @@ "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", "dev": true }, - "node_modules/@types/semver": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.5.tgz", - "integrity": "sha512-+d+WYC1BxJ6yVOgUgzK8gWvp5qF8ssV5r4nsDcZWKRWcDQLQ619tvWAxJQYGgBrO1MnLJC7a5GtiYsAoQ47dJg==", - "dev": true, - "peer": true - }, "node_modules/@types/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz", @@ -2500,208 +2483,12 @@ "integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==", "dev": true }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.10.0.tgz", - "integrity": "sha512-uoLj4g2OTL8rfUQVx2AFO1hp/zja1wABJq77P6IclQs6I/m9GLrm7jCdgzZkvWdDCQf1uEvoa8s8CupsgWQgVg==", - "dev": true, - "peer": true, - "dependencies": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.10.0", - "@typescript-eslint/type-utils": "6.10.0", - "@typescript-eslint/utils": "6.10.0", - "@typescript-eslint/visitor-keys": "6.10.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.4", - "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.10.0.tgz", - "integrity": "sha512-+sZwIj+s+io9ozSxIWbNB5873OSdfeBEH/FR0re14WLI6BaKuSOnnwCJ2foUiu8uXf4dRp1UqHP0vrZ1zXGrog==", - "dev": true, - "peer": true, - "dependencies": { - "@typescript-eslint/scope-manager": "6.10.0", - "@typescript-eslint/types": "6.10.0", - "@typescript-eslint/typescript-estree": "6.10.0", - "@typescript-eslint/visitor-keys": "6.10.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.10.0.tgz", - "integrity": "sha512-TN/plV7dzqqC2iPNf1KrxozDgZs53Gfgg5ZHyw8erd6jd5Ta/JIEcdCheXFt9b1NYb93a1wmIIVW/2gLkombDg==", - "dev": true, - "peer": true, - "dependencies": { - "@typescript-eslint/types": "6.10.0", - "@typescript-eslint/visitor-keys": "6.10.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.10.0.tgz", - "integrity": "sha512-wYpPs3hgTFblMYwbYWPT3eZtaDOjbLyIYuqpwuLBBqhLiuvJ+9sEp2gNRJEtR5N/c9G1uTtQQL5AhV0fEPJYcg==", - "dev": true, - "peer": true, - "dependencies": { - "@typescript-eslint/typescript-estree": "6.10.0", - "@typescript-eslint/utils": "6.10.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.10.0.tgz", - "integrity": "sha512-36Fq1PWh9dusgo3vH7qmQAj5/AZqARky1Wi6WpINxB6SkQdY5vQoT2/7rW7uBIsPDcvvGCLi4r10p0OJ7ITAeg==", - "dev": true, - "peer": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.10.0.tgz", - "integrity": "sha512-ek0Eyuy6P15LJVeghbWhSrBCj/vJpPXXR+EpaRZqou7achUWL8IdYnMSC5WHAeTWswYQuP2hAZgij/bC9fanBg==", - "dev": true, - "peer": true, - "dependencies": { - "@typescript-eslint/types": "6.10.0", - "@typescript-eslint/visitor-keys": "6.10.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.10.0.tgz", - "integrity": "sha512-v+pJ1/RcVyRc0o4wAGux9x42RHmAjIGzPRo538Z8M1tVx6HOnoQBCX/NoadHQlZeC+QO2yr4nNSFWOoraZCAyg==", - "dev": true, - "peer": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.10.0", - "@typescript-eslint/types": "6.10.0", - "@typescript-eslint/typescript-estree": "6.10.0", - "semver": "^7.5.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.10.0.tgz", - "integrity": "sha512-xMGluxQIEtOM7bqFCo+rCMh5fqI+ZxV5RUUOa29iVPz1OgCZrtc7rFnz5cLUazlkPKYqX+75iuDq7m0HQ48nCg==", - "dev": true, - "peer": true, - "dependencies": { - "@typescript-eslint/types": "6.10.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true + "dev": true, + "peer": true }, "node_modules/@vitest/coverage-v8": { "version": "2.1.4", @@ -2867,6 +2654,7 @@ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "peer": true, "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -2913,6 +2701,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -2942,9 +2731,9 @@ } }, "node_modules/algosdk": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/algosdk/-/algosdk-2.7.0.tgz", - "integrity": "sha512-sBE9lpV7bup3rZ+q2j3JQaFAE9JwZvjWKX00vPlG8e9txctXbgLL56jZhSWZndqhDI9oI+0P4NldkuQIWdrUyg==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/algosdk/-/algosdk-2.9.0.tgz", + "integrity": "sha512-o0n0nLMbTX6SFQdMUk2/2sy50jmEmZk5OTPYSh2aAeP8DUPxrhjMPfwGsYNvaO+qk75MixC2eWpfA9vygCQ/Mg==", "peer": true, "dependencies": { "algo-msgpack-with-bigint": "^2.1.1", @@ -3065,16 +2854,6 @@ "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", "dev": true }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, "node_modules/arraybuffer.prototype.slice": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", @@ -3196,16 +2975,6 @@ "node": ">= 12" } }, - "node_modules/big-integer": { - "version": "1.6.51", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", - "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.6" - } - }, "node_modules/bignumber.js": { "version": "9.1.2", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", @@ -3230,19 +2999,6 @@ "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==", "dev": true }, - "node_modules/bplist-parser": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz", - "integrity": "sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==", - "dev": true, - "peer": true, - "dependencies": { - "big-integer": "^1.6.44" - }, - "engines": { - "node": ">= 5.10.0" - } - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -3294,22 +3050,6 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, - "node_modules/bundle-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", - "integrity": "sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==", - "dev": true, - "peer": true, - "dependencies": { - "run-applescript": "^5.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/cac": { "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", @@ -3374,6 +3114,12 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/change-case": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz", + "integrity": "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==", + "dev": true + }, "node_modules/char-regex": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", @@ -3564,6 +3310,15 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, "node_modules/compare-func": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", @@ -3848,9 +3603,9 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "dependencies": { "path-key": "^3.1.0", @@ -3945,43 +3700,8 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/default-browser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz", - "integrity": "sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==", "dev": true, - "peer": true, - "dependencies": { - "bundle-name": "^3.0.0", - "default-browser-id": "^3.0.0", - "execa": "^7.1.1", - "titleize": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser-id": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz", - "integrity": "sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==", - "dev": true, - "peer": true, - "dependencies": { - "bplist-parser": "^0.2.0", - "untildify": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "peer": true }, "node_modules/define-data-property": { "version": "1.1.1", @@ -3997,19 +3717,6 @@ "node": ">= 0.4" } }, - "node_modules/define-lazy-prop": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", - "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/define-properties": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", @@ -4053,6 +3760,7 @@ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, + "peer": true, "dependencies": { "esutils": "^2.0.2" }, @@ -4367,6 +4075,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "peer": true, "engines": { "node": ">=10" }, @@ -4379,6 +4088,7 @@ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -4430,11 +4140,10 @@ } }, "node_modules/eslint-config-prettier": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz", - "integrity": "sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", "dev": true, - "peer": true, "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -4442,41 +4151,12 @@ "eslint": ">=7.0.0" } }, - "node_modules/eslint-plugin-prettier": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.1.tgz", - "integrity": "sha512-m3u5RnR56asrwV/lDC4GHorlW75DsFfmUcjfCYylTUs85dBRnB7VM6xG8eCMJdeDRnppzmxZVf1GEPJvl1JmNg==", - "dev": true, - "peer": true, - "dependencies": { - "prettier-linter-helpers": "^1.0.0", - "synckit": "^0.8.5" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/prettier" - }, - "peerDependencies": { - "@types/eslint": ">=8.0.0", - "eslint": ">=8.0.0", - "prettier": ">=3.0.0" - }, - "peerDependenciesMeta": { - "@types/eslint": { - "optional": true - }, - "eslint-config-prettier": { - "optional": true - } - } - }, "node_modules/eslint-scope": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, + "peer": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -4500,11 +4180,22 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true, + "peer": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/espree": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, + "peer": true, "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", @@ -4522,6 +4213,7 @@ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, + "peer": true, "dependencies": { "estraverse": "^5.1.0" }, @@ -4534,6 +4226,7 @@ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "peer": true, "dependencies": { "estraverse": "^5.2.0" }, @@ -4546,6 +4239,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "peer": true, "engines": { "node": ">=4.0" } @@ -4561,32 +4255,9 @@ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/execa": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", - "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", - "dev": true, "peer": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.1", - "human-signals": "^4.3.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^3.0.7", - "strip-final-newline": "^3.0.0" - }, "engines": { - "node": "^14.18.0 || ^16.14.0 || >=18.0.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "node": ">=0.10.0" } }, "node_modules/expect-type": { @@ -4604,13 +4275,6 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true, - "peer": true - }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", @@ -4643,13 +4307,15 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "dev": true, + "peer": true }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "dev": true, + "peer": true }, "node_modules/fastq": { "version": "1.15.0", @@ -4680,6 +4346,7 @@ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, + "peer": true, "dependencies": { "flat-cache": "^3.0.4" }, @@ -4704,6 +4371,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, + "peer": true, "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -4747,6 +4415,7 @@ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.1.tgz", "integrity": "sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==", "dev": true, + "peer": true, "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.3", @@ -4761,6 +4430,7 @@ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, + "peer": true, "dependencies": { "glob": "^7.1.3" }, @@ -4775,7 +4445,8 @@ "version": "3.2.9", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", - "dev": true + "dev": true, + "peer": true }, "node_modules/for-each": { "version": "0.3.3", @@ -5011,6 +4682,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "peer": true, "dependencies": { "is-glob": "^4.0.3" }, @@ -5038,6 +4710,7 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, + "peer": true, "dependencies": { "type-fest": "^0.20.2" }, @@ -5063,27 +4736,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "peer": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -5274,16 +4926,6 @@ "node": ">= 14" } }, - "node_modules/human-signals": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", - "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", - "dev": true, - "peer": true, - "engines": { - "node": ">=14.18.0" - } - }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -5304,9 +4946,9 @@ ] }, "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "engines": { "node": ">= 4" @@ -5356,6 +4998,7 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, + "peer": true, "engines": { "node": ">=0.8.19" } @@ -5538,22 +5181,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-docker": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", - "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", - "dev": true, - "peer": true, - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -5584,25 +5211,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-inside-container": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", - "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", - "dev": true, - "peer": true, - "dependencies": { - "is-docker": "^3.0.0" - }, - "bin": { - "is-inside-container": "cli.js" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", @@ -5653,6 +5261,7 @@ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, + "peer": true, "engines": { "node": ">=8" } @@ -5778,35 +5387,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "peer": true, - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-wsl/node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true, - "peer": true, - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -5979,7 +5559,8 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true + "dev": true, + "peer": true }, "node_modules/json-parse-better-errors": { "version": "1.0.2", @@ -5997,13 +5578,15 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "peer": true }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true + "dev": true, + "peer": true }, "node_modules/json-stringify-safe": { "version": "5.0.1", @@ -6038,6 +5621,15 @@ "node >= 0.2.0" ] }, + "node_modules/jsonschema": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", + "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/JSONStream": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", @@ -6071,6 +5663,7 @@ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, + "peer": true, "dependencies": { "json-buffer": "3.0.1" } @@ -6080,6 +5673,7 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "peer": true, "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -6114,6 +5708,7 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, + "peer": true, "dependencies": { "p-locate": "^5.0.0" }, @@ -6570,9 +6165,9 @@ } }, "node_modules/npm": { - "version": "10.5.2", - "resolved": "https://registry.npmjs.org/npm/-/npm-10.5.2.tgz", - "integrity": "sha512-cHVG7QEJwJdZyOrK0dKX5uf3R5Fd0E8AcmSES1jLtO52UT1enUKZ96Onw/xwq4CbrTZEnDuu2Vf9kCQh/Sd12w==", + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/npm/-/npm-10.9.1.tgz", + "integrity": "sha512-yJUw03xLqjiv1D52oHeoS5qmOEC5hkJlhP1cWlSrCgshuxWVyFEEK3M3hLC0NwbTaklLTYrhoIanYsuNP5WUKg==", "bundleDependencies": [ "@isaacs/string-locale-compare", "@npmcli/arborist", @@ -6590,8 +6185,6 @@ "chalk", "ci-info", "cli-columns", - "cli-table3", - "columnify", "fastest-levenshtein", "fs-minipass", "glob", @@ -6627,7 +6220,6 @@ "npm-profile", "npm-registry-fetch", "npm-user-validate", - "npmlog", "p-map", "pacote", "parse-conflict-json", @@ -6649,76 +6241,73 @@ "dev": true, "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/arborist": "^7.2.1", - "@npmcli/config": "^8.0.2", - "@npmcli/fs": "^3.1.0", - "@npmcli/map-workspaces": "^3.0.6", - "@npmcli/package-json": "^5.0.2", - "@npmcli/promise-spawn": "^7.0.1", - "@npmcli/redact": "^1.1.0", - "@npmcli/run-script": "^7.0.4", - "@sigstore/tuf": "^2.3.2", - "abbrev": "^2.0.0", + "@npmcli/arborist": "^8.0.0", + "@npmcli/config": "^9.0.0", + "@npmcli/fs": "^4.0.0", + "@npmcli/map-workspaces": "^4.0.1", + "@npmcli/package-json": "^6.0.1", + "@npmcli/promise-spawn": "^8.0.2", + "@npmcli/redact": "^3.0.0", + "@npmcli/run-script": "^9.0.1", + "@sigstore/tuf": "^3.0.0", + "abbrev": "^3.0.0", "archy": "~1.0.0", - "cacache": "^18.0.2", + "cacache": "^19.0.1", "chalk": "^5.3.0", - "ci-info": "^4.0.0", + "ci-info": "^4.1.0", "cli-columns": "^4.0.0", - "cli-table3": "^0.6.4", - "columnify": "^1.6.0", "fastest-levenshtein": "^1.0.16", "fs-minipass": "^3.0.3", - "glob": "^10.3.12", + "glob": "^10.4.5", "graceful-fs": "^4.2.11", - "hosted-git-info": "^7.0.1", - "ini": "^4.1.2", - "init-package-json": "^6.0.2", - "is-cidr": "^5.0.5", - "json-parse-even-better-errors": "^3.0.1", - "libnpmaccess": "^8.0.1", - "libnpmdiff": "^6.0.3", - "libnpmexec": "^7.0.4", - "libnpmfund": "^5.0.1", - "libnpmhook": "^10.0.0", - "libnpmorg": "^6.0.1", - "libnpmpack": "^6.0.3", - "libnpmpublish": "^9.0.2", - "libnpmsearch": "^7.0.0", - "libnpmteam": "^6.0.0", - "libnpmversion": "^5.0.1", - "make-fetch-happen": "^13.0.0", - "minimatch": "^9.0.4", - "minipass": "^7.0.4", + "hosted-git-info": "^8.0.2", + "ini": "^5.0.0", + "init-package-json": "^7.0.1", + "is-cidr": "^5.1.0", + "json-parse-even-better-errors": "^4.0.0", + "libnpmaccess": "^9.0.0", + "libnpmdiff": "^7.0.0", + "libnpmexec": "^9.0.0", + "libnpmfund": "^6.0.0", + "libnpmhook": "^11.0.0", + "libnpmorg": "^7.0.0", + "libnpmpack": "^8.0.0", + "libnpmpublish": "^10.0.1", + "libnpmsearch": "^8.0.0", + "libnpmteam": "^7.0.0", + "libnpmversion": "^7.0.0", + "make-fetch-happen": "^14.0.3", + "minimatch": "^9.0.5", + "minipass": "^7.1.1", "minipass-pipeline": "^1.2.4", "ms": "^2.1.2", - "node-gyp": "^10.1.0", - "nopt": "^7.2.0", - "normalize-package-data": "^6.0.0", - "npm-audit-report": "^5.0.0", - "npm-install-checks": "^6.3.0", - "npm-package-arg": "^11.0.1", - "npm-pick-manifest": "^9.0.0", - "npm-profile": "^9.0.0", - "npm-registry-fetch": "^16.2.0", - "npm-user-validate": "^2.0.0", - "npmlog": "^7.0.1", + "node-gyp": "^10.2.0", + "nopt": "^8.0.0", + "normalize-package-data": "^7.0.0", + "npm-audit-report": "^6.0.0", + "npm-install-checks": "^7.1.1", + "npm-package-arg": "^12.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-profile": "^11.0.1", + "npm-registry-fetch": "^18.0.2", + "npm-user-validate": "^3.0.0", "p-map": "^4.0.0", - "pacote": "^17.0.6", - "parse-conflict-json": "^3.0.1", - "proc-log": "^3.0.0", + "pacote": "^19.0.1", + "parse-conflict-json": "^4.0.0", + "proc-log": "^5.0.0", "qrcode-terminal": "^0.12.0", - "read": "^3.0.1", - "semver": "^7.6.0", + "read": "^4.0.0", + "semver": "^7.6.3", "spdx-expression-parse": "^4.0.0", - "ssri": "^10.0.5", + "ssri": "^12.0.0", "supports-color": "^9.4.0", "tar": "^6.2.1", "text-table": "~0.2.0", "tiny-relative-date": "^1.3.0", "treeverse": "^3.0.0", - "validate-npm-package-name": "^5.0.0", - "which": "^4.0.0", - "write-file-atomic": "^5.0.1" + "validate-npm-package-name": "^6.0.0", + "which": "^5.0.0", + "write-file-atomic": "^6.0.0" }, "bin": { "npm": "bin/npm-cli.js", @@ -6795,9 +6384,9 @@ "dev": true }, "node_modules/npm-run-all/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", + "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", "dev": true, "dependencies": { "nice-try": "^1.0.4", @@ -6918,16 +6507,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/npm/node_modules/@colors/colors": { - "version": "1.5.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.1.90" - } - }, "node_modules/npm/node_modules/@isaacs/cliui": { "version": "8.0.2", "dev": true, @@ -6946,7 +6525,7 @@ } }, "node_modules/npm/node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", + "version": "6.1.0", "dev": true, "inBundle": true, "license": "MIT", @@ -6995,6 +6574,18 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/npm/node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/npm/node_modules/@isaacs/string-locale-compare": { "version": "1.1.0", "dev": true, @@ -7002,7 +6593,7 @@ "license": "ISC" }, "node_modules/npm/node_modules/@npmcli/agent": { - "version": "2.2.2", + "version": "3.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -7014,47 +6605,48 @@ "socks-proxy-agent": "^8.0.3" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/arborist": { - "version": "7.4.2", + "version": "8.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/fs": "^3.1.0", - "@npmcli/installed-package-contents": "^2.0.2", - "@npmcli/map-workspaces": "^3.0.2", - "@npmcli/metavuln-calculator": "^7.0.0", - "@npmcli/name-from-folder": "^2.0.0", - "@npmcli/node-gyp": "^3.0.0", - "@npmcli/package-json": "^5.0.0", - "@npmcli/query": "^3.1.0", - "@npmcli/redact": "^1.1.0", - "@npmcli/run-script": "^7.0.2", - "bin-links": "^4.0.1", - "cacache": "^18.0.0", + "@npmcli/fs": "^4.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/map-workspaces": "^4.0.1", + "@npmcli/metavuln-calculator": "^8.0.0", + "@npmcli/name-from-folder": "^3.0.0", + "@npmcli/node-gyp": "^4.0.0", + "@npmcli/package-json": "^6.0.1", + "@npmcli/query": "^4.0.0", + "@npmcli/redact": "^3.0.0", + "@npmcli/run-script": "^9.0.1", + "bin-links": "^5.0.0", + "cacache": "^19.0.1", "common-ancestor-path": "^1.0.1", - "hosted-git-info": "^7.0.1", - "json-parse-even-better-errors": "^3.0.0", + "hosted-git-info": "^8.0.0", + "json-parse-even-better-errors": "^4.0.0", "json-stringify-nice": "^1.1.4", + "lru-cache": "^10.2.2", "minimatch": "^9.0.4", - "nopt": "^7.0.0", - "npm-install-checks": "^6.2.0", - "npm-package-arg": "^11.0.1", - "npm-pick-manifest": "^9.0.0", - "npm-registry-fetch": "^16.2.0", - "npmlog": "^7.0.1", - "pacote": "^17.0.4", - "parse-conflict-json": "^3.0.0", - "proc-log": "^3.0.0", + "nopt": "^8.0.0", + "npm-install-checks": "^7.1.0", + "npm-package-arg": "^12.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.1", + "pacote": "^19.0.0", + "parse-conflict-json": "^4.0.0", + "proc-log": "^5.0.0", + "proggy": "^3.0.0", "promise-all-reject-late": "^1.0.0", "promise-call-limit": "^3.0.1", - "read-package-json-fast": "^3.0.2", + "read-package-json-fast": "^4.0.0", "semver": "^7.3.7", - "ssri": "^10.0.5", + "ssri": "^12.0.0", "treeverse": "^3.0.0", "walk-up-path": "^3.0.1" }, @@ -7062,57 +6654,30 @@ "arborist": "bin/index.js" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/config": { - "version": "8.2.2", + "version": "9.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/map-workspaces": "^3.0.2", + "@npmcli/map-workspaces": "^4.0.1", + "@npmcli/package-json": "^6.0.1", "ci-info": "^4.0.0", - "ini": "^4.1.2", - "nopt": "^7.0.0", - "proc-log": "^3.0.0", - "read-package-json-fast": "^3.0.2", + "ini": "^5.0.0", + "nopt": "^8.0.0", + "proc-log": "^5.0.0", "semver": "^7.3.5", "walk-up-path": "^3.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/disparity-colors": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "ansi-styles": "^4.3.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/disparity-colors/node_modules/ansi-styles": { - "version": "4.3.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/fs": { - "version": "3.1.0", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -7120,157 +6685,191 @@ "semver": "^7.3.5" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/git": { - "version": "5.0.5", + "version": "6.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/promise-spawn": "^7.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "ini": "^5.0.0", "lru-cache": "^10.0.1", - "npm-pick-manifest": "^9.0.0", - "proc-log": "^3.0.0", + "npm-pick-manifest": "^10.0.0", + "proc-log": "^5.0.0", "promise-inflight": "^1.0.1", "promise-retry": "^2.0.1", "semver": "^7.3.5", - "which": "^4.0.0" + "which": "^5.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/installed-package-contents": { - "version": "2.0.2", + "version": "3.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-bundled": "^3.0.0", - "npm-normalize-package-bin": "^3.0.0" + "npm-bundled": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" }, "bin": { - "installed-package-contents": "lib/index.js" + "installed-package-contents": "bin/index.js" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/map-workspaces": { - "version": "3.0.6", + "version": "4.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/name-from-folder": "^2.0.0", + "@npmcli/name-from-folder": "^3.0.0", + "@npmcli/package-json": "^6.0.0", "glob": "^10.2.2", - "minimatch": "^9.0.0", - "read-package-json-fast": "^3.0.0" + "minimatch": "^9.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { - "version": "7.0.0", + "version": "8.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "cacache": "^18.0.0", - "json-parse-even-better-errors": "^3.0.0", - "pacote": "^17.0.0", + "cacache": "^19.0.0", + "json-parse-even-better-errors": "^4.0.0", + "pacote": "^20.0.0", + "proc-log": "^5.0.0", "semver": "^7.3.5" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/npm/node_modules/@npmcli/name-from-folder": { - "version": "2.0.0", + "node_modules/npm/node_modules/@npmcli/metavuln-calculator/node_modules/pacote": { + "version": "20.0.0", "dev": true, "inBundle": true, "license": "ISC", + "dependencies": { + "@npmcli/git": "^6.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "@npmcli/run-script": "^9.0.0", + "cacache": "^19.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^12.0.0", + "npm-packlist": "^9.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^3.0.0", + "ssri": "^12.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "bin/index.js" + }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/npm/node_modules/@npmcli/node-gyp": { + "node_modules/npm/node_modules/@npmcli/name-from-folder": { "version": "3.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/node-gyp": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/package-json": { - "version": "5.0.2", + "version": "6.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/git": "^5.0.0", + "@npmcli/git": "^6.0.0", "glob": "^10.2.2", - "hosted-git-info": "^7.0.0", - "json-parse-even-better-errors": "^3.0.0", - "normalize-package-data": "^6.0.0", - "proc-log": "^3.0.0", + "hosted-git-info": "^8.0.0", + "json-parse-even-better-errors": "^4.0.0", + "normalize-package-data": "^7.0.0", + "proc-log": "^5.0.0", "semver": "^7.5.3" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/promise-spawn": { - "version": "7.0.1", + "version": "8.0.2", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "which": "^4.0.0" + "which": "^5.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/query": { - "version": "3.1.0", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "postcss-selector-parser": "^6.0.10" + "postcss-selector-parser": "^6.1.2" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/redact": { - "version": "1.1.0", + "version": "3.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@npmcli/run-script": { - "version": "7.0.4", + "version": "9.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/node-gyp": "^3.0.0", - "@npmcli/package-json": "^5.0.0", - "@npmcli/promise-spawn": "^7.0.0", + "@npmcli/node-gyp": "^4.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", "node-gyp": "^10.0.0", - "which": "^4.0.0" + "proc-log": "^5.0.0", + "which": "^5.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@pkgjs/parseargs": { @@ -7283,76 +6882,26 @@ "node": ">=14" } }, - "node_modules/npm/node_modules/@sigstore/bundle": { - "version": "2.3.1", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/protobuf-specs": "^0.3.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@sigstore/core": { - "version": "1.1.0", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, "node_modules/npm/node_modules/@sigstore/protobuf-specs": { - "version": "0.3.1", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@sigstore/sign": { - "version": "2.3.0", + "version": "0.3.2", "dev": true, "inBundle": true, "license": "Apache-2.0", - "dependencies": { - "@sigstore/bundle": "^2.3.0", - "@sigstore/core": "^1.0.0", - "@sigstore/protobuf-specs": "^0.3.1", - "make-fetch-happen": "^13.0.0" - }, "engines": { "node": "^16.14.0 || >=18.0.0" } }, "node_modules/npm/node_modules/@sigstore/tuf": { - "version": "2.3.2", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/protobuf-specs": "^0.3.0", - "tuf-js": "^2.2.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@sigstore/verify": { - "version": "1.2.0", + "version": "3.0.0", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@sigstore/bundle": "^2.3.1", - "@sigstore/core": "^1.1.0", - "@sigstore/protobuf-specs": "^0.3.1" + "@sigstore/protobuf-specs": "^0.3.2", + "tuf-js": "^3.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@tufjs/canonical-json": { @@ -7364,26 +6913,13 @@ "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/npm/node_modules/@tufjs/models": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "@tufjs/canonical-json": "2.0.0", - "minimatch": "^9.0.3" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, "node_modules/npm/node_modules/abbrev": { - "version": "2.0.0", + "version": "3.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/agent-base": { @@ -7444,15 +6980,6 @@ "inBundle": true, "license": "MIT" }, - "node_modules/npm/node_modules/are-we-there-yet": { - "version": "4.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, "node_modules/npm/node_modules/balanced-match": { "version": "1.0.2", "dev": true, @@ -7460,18 +6987,19 @@ "license": "MIT" }, "node_modules/npm/node_modules/bin-links": { - "version": "4.0.3", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "cmd-shim": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0", - "read-cmd-shim": "^4.0.0", - "write-file-atomic": "^5.0.0" + "cmd-shim": "^7.0.0", + "npm-normalize-package-bin": "^4.0.0", + "proc-log": "^5.0.0", + "read-cmd-shim": "^5.0.0", + "write-file-atomic": "^6.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/binary-extensions": { @@ -7495,22 +7023,13 @@ "balanced-match": "^1.0.0" } }, - "node_modules/npm/node_modules/builtins": { - "version": "5.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "semver": "^7.0.0" - } - }, "node_modules/npm/node_modules/cacache": { - "version": "18.0.2", + "version": "19.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/fs": "^3.1.0", + "@npmcli/fs": "^4.0.0", "fs-minipass": "^3.0.0", "glob": "^10.2.2", "lru-cache": "^10.0.1", @@ -7518,13 +7037,88 @@ "minipass-collect": "^2.0.1", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", - "p-map": "^4.0.0", - "ssri": "^10.0.0", - "tar": "^6.1.11", - "unique-filename": "^3.0.0" + "p-map": "^7.0.2", + "ssri": "^12.0.0", + "tar": "^7.4.3", + "unique-filename": "^4.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/cacache/node_modules/chownr": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/npm/node_modules/cacache/node_modules/minizlib": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.4", + "rimraf": "^5.0.5" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/npm/node_modules/cacache/node_modules/mkdirp": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/cacache/node_modules/p-map": { + "version": "7.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/cacache/node_modules/tar": { + "version": "7.4.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/npm/node_modules/cacache/node_modules/yallist": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" } }, "node_modules/npm/node_modules/chalk": { @@ -7549,7 +7143,7 @@ } }, "node_modules/npm/node_modules/ci-info": { - "version": "4.0.0", + "version": "4.1.0", "dev": true, "funding": [ { @@ -7564,7 +7158,7 @@ } }, "node_modules/npm/node_modules/cidr-regex": { - "version": "4.0.5", + "version": "4.1.1", "dev": true, "inBundle": true, "license": "BSD-2-Clause", @@ -7597,37 +7191,13 @@ "node": ">= 10" } }, - "node_modules/npm/node_modules/cli-table3": { - "version": "0.6.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "string-width": "^4.2.0" - }, - "engines": { - "node": "10.* || >= 12.*" - }, - "optionalDependencies": { - "@colors/colors": "1.5.0" - } - }, - "node_modules/npm/node_modules/clone": { - "version": "1.0.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, "node_modules/npm/node_modules/cmd-shim": { - "version": "6.0.2", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/color-convert": { @@ -7648,42 +7218,14 @@ "inBundle": true, "license": "MIT" }, - "node_modules/npm/node_modules/color-support": { - "version": "1.1.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "bin": { - "color-support": "bin.js" - } - }, - "node_modules/npm/node_modules/columnify": { - "version": "1.6.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "strip-ansi": "^6.0.1", - "wcwidth": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/npm/node_modules/common-ancestor-path": { "version": "1.0.1", "dev": true, "inBundle": true, "license": "ISC" }, - "node_modules/npm/node_modules/console-control-strings": { - "version": "1.1.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, "node_modules/npm/node_modules/cross-spawn": { - "version": "7.0.3", + "version": "7.0.6", "dev": true, "inBundle": true, "license": "MIT", @@ -7724,12 +7266,12 @@ } }, "node_modules/npm/node_modules/debug": { - "version": "4.3.4", + "version": "4.3.7", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -7740,32 +7282,14 @@ } } }, - "node_modules/npm/node_modules/debug/node_modules/ms": { - "version": "2.1.2", + "node_modules/npm/node_modules/diff": { + "version": "5.2.0", "dev": true, "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/defaults": { - "version": "1.0.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "clone": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm/node_modules/diff": { - "version": "5.2.0", - "dev": true, - "inBundle": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } }, "node_modules/npm/node_modules/eastasianwidth": { "version": "0.2.0", @@ -7820,7 +7344,7 @@ } }, "node_modules/npm/node_modules/foreground-child": { - "version": "3.1.1", + "version": "3.3.0", "dev": true, "inBundle": true, "license": "ISC", @@ -7847,52 +7371,22 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/npm/node_modules/function-bind": { - "version": "1.1.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/npm/node_modules/gauge": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^4.0.1", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, "node_modules/npm/node_modules/glob": { - "version": "10.3.12", + "version": "10.4.5", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", - "jackspeak": "^2.3.6", - "minimatch": "^9.0.1", - "minipass": "^7.0.4", - "path-scurry": "^1.10.2" + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, "funding": { "url": "https://github.com/sponsors/isaacs" } @@ -7903,26 +7397,8 @@ "inBundle": true, "license": "ISC" }, - "node_modules/npm/node_modules/has-unicode": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/hasown": { - "version": "2.0.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/npm/node_modules/hosted-git-info": { - "version": "7.0.1", + "version": "8.0.2", "dev": true, "inBundle": true, "license": "ISC", @@ -7930,7 +7406,7 @@ "lru-cache": "^10.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/http-cache-semantics": { @@ -7953,7 +7429,7 @@ } }, "node_modules/npm/node_modules/https-proxy-agent": { - "version": "7.0.4", + "version": "7.0.5", "dev": true, "inBundle": true, "license": "MIT", @@ -7979,7 +7455,7 @@ } }, "node_modules/npm/node_modules/ignore-walk": { - "version": "6.0.4", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -7987,7 +7463,7 @@ "minimatch": "^9.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/imurmurhash": { @@ -8009,30 +7485,30 @@ } }, "node_modules/npm/node_modules/ini": { - "version": "4.1.2", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/init-package-json": { - "version": "6.0.2", + "version": "7.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/package-json": "^5.0.0", - "npm-package-arg": "^11.0.0", - "promzard": "^1.0.0", - "read": "^3.0.1", + "@npmcli/package-json": "^6.0.0", + "npm-package-arg": "^12.0.0", + "promzard": "^2.0.0", + "read": "^4.0.0", "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4", - "validate-npm-package-name": "^5.0.0" + "validate-npm-package-name": "^6.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/ip-address": { @@ -8048,12 +7524,6 @@ "node": ">= 12" } }, - "node_modules/npm/node_modules/ip-address/node_modules/sprintf-js": { - "version": "1.1.3", - "dev": true, - "inBundle": true, - "license": "BSD-3-Clause" - }, "node_modules/npm/node_modules/ip-regex": { "version": "5.0.0", "dev": true, @@ -8067,29 +7537,17 @@ } }, "node_modules/npm/node_modules/is-cidr": { - "version": "5.0.5", + "version": "5.1.0", "dev": true, "inBundle": true, "license": "BSD-2-Clause", "dependencies": { - "cidr-regex": "^4.0.4" + "cidr-regex": "^4.1.1" }, "engines": { "node": ">=14" } }, - "node_modules/npm/node_modules/is-core-module": { - "version": "2.13.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/npm/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "dev": true, @@ -8112,16 +7570,13 @@ "license": "ISC" }, "node_modules/npm/node_modules/jackspeak": { - "version": "2.3.6", + "version": "3.4.3", "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" }, - "engines": { - "node": ">=14" - }, "funding": { "url": "https://github.com/sponsors/isaacs" }, @@ -8136,12 +7591,12 @@ "license": "MIT" }, "node_modules/npm/node_modules/json-parse-even-better-errors": { - "version": "3.0.1", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "MIT", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/json-stringify-nice": { @@ -8175,206 +7630,210 @@ "license": "MIT" }, "node_modules/npm/node_modules/libnpmaccess": { - "version": "8.0.3", + "version": "9.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-package-arg": "^11.0.1", - "npm-registry-fetch": "^16.2.0" + "npm-package-arg": "^12.0.0", + "npm-registry-fetch": "^18.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmdiff": { - "version": "6.0.9", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^7.2.1", - "@npmcli/disparity-colors": "^3.0.0", - "@npmcli/installed-package-contents": "^2.0.2", + "@npmcli/arborist": "^8.0.0", + "@npmcli/installed-package-contents": "^3.0.0", "binary-extensions": "^2.3.0", "diff": "^5.1.0", "minimatch": "^9.0.4", - "npm-package-arg": "^11.0.1", - "pacote": "^17.0.4", + "npm-package-arg": "^12.0.0", + "pacote": "^19.0.0", "tar": "^6.2.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmexec": { - "version": "7.0.10", + "version": "9.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^7.2.1", - "@npmcli/run-script": "^7.0.2", + "@npmcli/arborist": "^8.0.0", + "@npmcli/run-script": "^9.0.1", "ci-info": "^4.0.0", - "npm-package-arg": "^11.0.1", - "npmlog": "^7.0.1", - "pacote": "^17.0.4", - "proc-log": "^3.0.0", - "read": "^3.0.1", - "read-package-json-fast": "^3.0.2", + "npm-package-arg": "^12.0.0", + "pacote": "^19.0.0", + "proc-log": "^5.0.0", + "read": "^4.0.0", + "read-package-json-fast": "^4.0.0", "semver": "^7.3.7", "walk-up-path": "^3.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmfund": { - "version": "5.0.7", + "version": "6.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^7.2.1" + "@npmcli/arborist": "^8.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmhook": { - "version": "10.0.2", + "version": "11.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^16.2.0" + "npm-registry-fetch": "^18.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmorg": { - "version": "6.0.3", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^16.2.0" + "npm-registry-fetch": "^18.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmpack": { - "version": "6.0.9", + "version": "8.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^7.2.1", - "@npmcli/run-script": "^7.0.2", - "npm-package-arg": "^11.0.1", - "pacote": "^17.0.4" + "@npmcli/arborist": "^8.0.0", + "@npmcli/run-script": "^9.0.1", + "npm-package-arg": "^12.0.0", + "pacote": "^19.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmpublish": { - "version": "9.0.5", + "version": "10.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "ci-info": "^4.0.0", - "normalize-package-data": "^6.0.0", - "npm-package-arg": "^11.0.1", - "npm-registry-fetch": "^16.2.0", - "proc-log": "^3.0.0", + "normalize-package-data": "^7.0.0", + "npm-package-arg": "^12.0.0", + "npm-registry-fetch": "^18.0.1", + "proc-log": "^5.0.0", "semver": "^7.3.7", - "sigstore": "^2.2.0", - "ssri": "^10.0.5" + "sigstore": "^3.0.0", + "ssri": "^12.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmsearch": { - "version": "7.0.2", + "version": "8.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-registry-fetch": "^16.2.0" + "npm-registry-fetch": "^18.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmteam": { - "version": "6.0.2", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^16.2.0" + "npm-registry-fetch": "^18.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmversion": { - "version": "5.0.2", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/git": "^5.0.3", - "@npmcli/run-script": "^7.0.2", - "json-parse-even-better-errors": "^3.0.0", - "proc-log": "^3.0.0", + "@npmcli/git": "^6.0.1", + "@npmcli/run-script": "^9.0.1", + "json-parse-even-better-errors": "^4.0.0", + "proc-log": "^5.0.0", "semver": "^7.3.7" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/lru-cache": { - "version": "10.2.0", + "version": "10.4.3", "dev": true, "inBundle": true, - "license": "ISC", - "engines": { - "node": "14 || >=16.14" - } + "license": "ISC" }, "node_modules/npm/node_modules/make-fetch-happen": { - "version": "13.0.0", + "version": "14.0.3", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/agent": "^2.0.0", - "cacache": "^18.0.0", + "@npmcli/agent": "^3.0.0", + "cacache": "^19.0.1", "http-cache-semantics": "^4.1.1", - "is-lambda": "^1.0.1", "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", + "minipass-fetch": "^4.0.0", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", + "negotiator": "^1.0.0", + "proc-log": "^5.0.0", "promise-retry": "^2.0.1", - "ssri": "^10.0.0" + "ssri": "^12.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/make-fetch-happen/node_modules/negotiator": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" } }, "node_modules/npm/node_modules/minimatch": { - "version": "9.0.4", + "version": "9.0.5", "dev": true, "inBundle": true, "license": "ISC", @@ -8389,7 +7848,7 @@ } }, "node_modules/npm/node_modules/minipass": { - "version": "7.0.4", + "version": "7.1.2", "dev": true, "inBundle": true, "license": "ISC", @@ -8410,57 +7869,48 @@ } }, "node_modules/npm/node_modules/minipass-fetch": { - "version": "3.0.4", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { "minipass": "^7.0.3", "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" + "minizlib": "^3.0.1" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" }, "optionalDependencies": { "encoding": "^0.1.13" } }, - "node_modules/npm/node_modules/minipass-flush": { - "version": "1.0.5", + "node_modules/npm/node_modules/minipass-fetch/node_modules/minizlib": { + "version": "3.0.1", "dev": true, "inBundle": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "minipass": "^3.0.0" + "minipass": "^7.0.4", + "rimraf": "^5.0.5" }, "engines": { - "node": ">= 8" + "node": ">= 18" } }, - "node_modules/npm/node_modules/minipass-flush/node_modules/minipass": { - "version": "3.3.6", + "node_modules/npm/node_modules/minipass-flush": { + "version": "1.0.5", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "yallist": "^4.0.0" + "minipass": "^3.0.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minipass-json-stream": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "jsonparse": "^1.3.1", - "minipass": "^3.0.0" + "node": ">= 8" } }, - "node_modules/npm/node_modules/minipass-json-stream/node_modules/minipass": { + "node_modules/npm/node_modules/minipass-flush/node_modules/minipass": { "version": "3.3.6", "dev": true, "inBundle": true, @@ -8564,16 +8014,16 @@ "license": "MIT" }, "node_modules/npm/node_modules/mute-stream": { - "version": "1.0.0", + "version": "2.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/negotiator": { - "version": "0.6.3", + "version": "0.6.4", "dev": true, "inBundle": true, "license": "MIT", @@ -8582,7 +8032,7 @@ } }, "node_modules/npm/node_modules/node-gyp": { - "version": "10.1.0", + "version": "10.2.0", "dev": true, "inBundle": true, "license": "MIT", @@ -8593,9 +8043,9 @@ "graceful-fs": "^4.2.6", "make-fetch-happen": "^13.0.0", "nopt": "^7.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.1.0", "semver": "^7.3.5", - "tar": "^6.1.2", + "tar": "^6.2.1", "which": "^4.0.0" }, "bin": { @@ -8605,38 +8055,36 @@ "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/npm/node_modules/nopt": { - "version": "7.2.0", + "node_modules/npm/node_modules/node-gyp/node_modules/@npmcli/agent": { + "version": "2.2.2", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "abbrev": "^2.0.0" - }, - "bin": { - "nopt": "bin/nopt.js" + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/npm/node_modules/normalize-package-data": { - "version": "6.0.0", + "node_modules/npm/node_modules/node-gyp/node_modules/@npmcli/fs": { + "version": "3.1.1", "dev": true, "inBundle": true, - "license": "BSD-2-Clause", + "license": "ISC", "dependencies": { - "hosted-git-info": "^7.0.0", - "is-core-module": "^2.8.1", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" + "semver": "^7.3.5" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/npm/node_modules/npm-audit-report": { - "version": "5.0.0", + "node_modules/npm/node_modules/node-gyp/node_modules/abbrev": { + "version": "2.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -8644,135 +8092,327 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/npm/node_modules/npm-bundled": { - "version": "3.0.0", + "node_modules/npm/node_modules/node-gyp/node_modules/cacache": { + "version": "18.0.4", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-normalize-package-bin": "^3.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/npm-install-checks": { - "version": "6.3.0", - "dev": true, - "inBundle": true, + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/isexe": { + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/make-fetch-happen": { + "version": "13.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/agent": "^2.0.0", + "cacache": "^18.0.0", + "http-cache-semantics": "^4.1.1", + "is-lambda": "^1.0.1", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "proc-log": "^4.2.0", + "promise-retry": "^2.0.1", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/minipass-fetch": { + "version": "3.0.5", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/nopt": { + "version": "7.2.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/proc-log": { + "version": "4.2.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/ssri": { + "version": "10.0.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/unique-filename": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/unique-slug": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/which": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/nopt": { + "version": "8.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/nopt/node_modules/abbrev": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/normalize-package-data": { + "version": "7.0.0", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^8.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/npm-audit-report": { + "version": "6.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/npm-bundled": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-normalize-package-bin": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/npm-install-checks": { + "version": "7.1.1", + "dev": true, + "inBundle": true, "license": "BSD-2-Clause", "dependencies": { "semver": "^7.1.1" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/npm-normalize-package-bin": { - "version": "3.0.1", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/npm-package-arg": { - "version": "11.0.1", + "version": "12.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "hosted-git-info": "^7.0.0", - "proc-log": "^3.0.0", + "hosted-git-info": "^8.0.0", + "proc-log": "^5.0.0", "semver": "^7.3.5", - "validate-npm-package-name": "^5.0.0" + "validate-npm-package-name": "^6.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/npm-packlist": { - "version": "8.0.2", + "version": "9.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "ignore-walk": "^6.0.4" + "ignore-walk": "^7.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/npm-pick-manifest": { - "version": "9.0.0", + "version": "10.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-install-checks": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0", - "npm-package-arg": "^11.0.0", + "npm-install-checks": "^7.1.0", + "npm-normalize-package-bin": "^4.0.0", + "npm-package-arg": "^12.0.0", "semver": "^7.3.5" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/npm-profile": { - "version": "9.0.0", + "version": "11.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-registry-fetch": "^16.0.0", - "proc-log": "^3.0.0" + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/npm-registry-fetch": { - "version": "16.2.0", + "version": "18.0.2", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/redact": "^1.1.0", - "make-fetch-happen": "^13.0.0", + "@npmcli/redact": "^3.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^14.0.0", "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", - "minipass-json-stream": "^1.0.1", - "minizlib": "^2.1.2", - "npm-package-arg": "^11.0.0", - "proc-log": "^3.0.0" + "minipass-fetch": "^4.0.0", + "minizlib": "^3.0.1", + "npm-package-arg": "^12.0.0", + "proc-log": "^5.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/npm/node_modules/npm-user-validate": { - "version": "2.0.0", + "node_modules/npm/node_modules/npm-registry-fetch/node_modules/minizlib": { + "version": "3.0.1", "dev": true, "inBundle": true, - "license": "BSD-2-Clause", + "license": "MIT", + "dependencies": { + "minipass": "^7.0.4", + "rimraf": "^5.0.5" + }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">= 18" } }, - "node_modules/npm/node_modules/npmlog": { - "version": "7.0.1", + "node_modules/npm/node_modules/npm-user-validate": { + "version": "3.0.0", "dev": true, "inBundle": true, - "license": "ISC", - "dependencies": { - "are-we-there-yet": "^4.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^5.0.0", - "set-blocking": "^2.0.0" - }, + "license": "BSD-2-Clause", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/p-map": { @@ -8790,50 +8430,55 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/npm/node_modules/package-json-from-dist": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0" + }, "node_modules/npm/node_modules/pacote": { - "version": "17.0.6", + "version": "19.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/git": "^5.0.0", - "@npmcli/installed-package-contents": "^2.0.1", - "@npmcli/promise-spawn": "^7.0.0", - "@npmcli/run-script": "^7.0.0", - "cacache": "^18.0.0", + "@npmcli/git": "^6.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "@npmcli/run-script": "^9.0.0", + "cacache": "^19.0.0", "fs-minipass": "^3.0.0", "minipass": "^7.0.2", - "npm-package-arg": "^11.0.0", - "npm-packlist": "^8.0.0", - "npm-pick-manifest": "^9.0.0", - "npm-registry-fetch": "^16.0.0", - "proc-log": "^3.0.0", + "npm-package-arg": "^12.0.0", + "npm-packlist": "^9.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0", "promise-retry": "^2.0.1", - "read-package-json": "^7.0.0", - "read-package-json-fast": "^3.0.0", - "sigstore": "^2.2.0", - "ssri": "^10.0.0", + "sigstore": "^3.0.0", + "ssri": "^12.0.0", "tar": "^6.1.11" }, "bin": { - "pacote": "lib/bin.js" + "pacote": "bin/index.js" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/parse-conflict-json": { - "version": "3.0.1", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "json-parse-even-better-errors": "^3.0.0", + "json-parse-even-better-errors": "^4.0.0", "just-diff": "^6.0.0", "just-diff-apply": "^5.2.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/path-key": { @@ -8846,7 +8491,7 @@ } }, "node_modules/npm/node_modules/path-scurry": { - "version": "1.10.2", + "version": "1.11.1", "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", @@ -8855,14 +8500,14 @@ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=16 || 14 >=14.18" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/npm/node_modules/postcss-selector-parser": { - "version": "6.0.16", + "version": "6.1.2", "dev": true, "inBundle": true, "license": "MIT", @@ -8875,12 +8520,21 @@ } }, "node_modules/npm/node_modules/proc-log": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/proggy": { "version": "3.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/promise-all-reject-late": { @@ -8893,7 +8547,7 @@ } }, "node_modules/npm/node_modules/promise-call-limit": { - "version": "3.0.1", + "version": "3.0.2", "dev": true, "inBundle": true, "license": "ISC", @@ -8921,15 +8575,15 @@ } }, "node_modules/npm/node_modules/promzard": { - "version": "1.0.1", + "version": "2.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "read": "^3.0.1" + "read": "^4.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/qrcode-terminal": { @@ -8941,52 +8595,37 @@ } }, "node_modules/npm/node_modules/read": { - "version": "3.0.1", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "mute-stream": "^1.0.0" + "mute-stream": "^2.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/read-cmd-shim": { - "version": "4.0.0", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/read-package-json": { - "version": "7.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "glob": "^10.2.2", - "json-parse-even-better-errors": "^3.0.0", - "normalize-package-data": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/read-package-json-fast": { - "version": "3.0.2", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "json-parse-even-better-errors": "^3.0.0", - "npm-normalize-package-bin": "^3.0.0" + "json-parse-even-better-errors": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/retry": { @@ -8998,46 +8637,40 @@ "node": ">= 4" } }, - "node_modules/npm/node_modules/safer-buffer": { - "version": "2.1.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "optional": true - }, - "node_modules/npm/node_modules/semver": { - "version": "7.6.0", + "node_modules/npm/node_modules/rimraf": { + "version": "5.0.10", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "lru-cache": "^6.0.0" + "glob": "^10.3.7" }, "bin": { - "semver": "bin/semver.js" + "rimraf": "dist/esm/bin.mjs" }, - "engines": { - "node": ">=10" + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/npm/node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", + "node_modules/npm/node_modules/safer-buffer": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/npm/node_modules/semver": { + "version": "7.6.3", "dev": true, "inBundle": true, "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" + "bin": { + "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, - "node_modules/npm/node_modules/set-blocking": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, "node_modules/npm/node_modules/shebang-command": { "version": "2.0.0", "dev": true, @@ -9072,20 +8705,72 @@ } }, "node_modules/npm/node_modules/sigstore": { - "version": "2.3.0", + "version": "3.0.0", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@sigstore/bundle": "^2.3.1", - "@sigstore/core": "^1.0.0", - "@sigstore/protobuf-specs": "^0.3.1", - "@sigstore/sign": "^2.3.0", - "@sigstore/tuf": "^2.3.1", - "@sigstore/verify": "^1.2.0" + "@sigstore/bundle": "^3.0.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "@sigstore/sign": "^3.0.0", + "@sigstore/tuf": "^3.0.0", + "@sigstore/verify": "^2.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/bundle": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.3.2" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/core": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/sign": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.0.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "make-fetch-happen": "^14.0.1", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/verify": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.0.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.3.2" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/smart-buffer": { @@ -9113,14 +8798,14 @@ } }, "node_modules/npm/node_modules/socks-proxy-agent": { - "version": "8.0.3", + "version": "8.0.4", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { "agent-base": "^7.1.1", "debug": "^4.3.4", - "socks": "^2.7.1" + "socks": "^2.8.3" }, "engines": { "node": ">= 14" @@ -9163,13 +8848,19 @@ } }, "node_modules/npm/node_modules/spdx-license-ids": { - "version": "3.0.17", + "version": "3.0.20", "dev": true, "inBundle": true, "license": "CC0-1.0" }, + "node_modules/npm/node_modules/sprintf-js": { + "version": "1.1.3", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause" + }, "node_modules/npm/node_modules/ssri": { - "version": "10.0.5", + "version": "12.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -9177,7 +8868,7 @@ "minipass": "^7.0.3" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/string-width": { @@ -9318,33 +9009,46 @@ } }, "node_modules/npm/node_modules/tuf-js": { - "version": "2.2.0", + "version": "3.0.1", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@tufjs/models": "2.0.0", - "debug": "^4.3.4", - "make-fetch-happen": "^13.0.0" + "@tufjs/models": "3.0.1", + "debug": "^4.3.6", + "make-fetch-happen": "^14.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/tuf-js/node_modules/@tufjs/models": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^9.0.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/unique-filename": { - "version": "3.0.0", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "unique-slug": "^4.0.0" + "unique-slug": "^5.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/unique-slug": { - "version": "4.0.0", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -9352,7 +9056,7 @@ "imurmurhash": "^0.1.4" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/util-deprecate": { @@ -9382,15 +9086,12 @@ } }, "node_modules/npm/node_modules/validate-npm-package-name": { - "version": "5.0.0", + "version": "6.0.0", "dev": true, "inBundle": true, "license": "ISC", - "dependencies": { - "builtins": "^5.0.0" - }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/walk-up-path": { @@ -9399,17 +9100,8 @@ "inBundle": true, "license": "ISC" }, - "node_modules/npm/node_modules/wcwidth": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "defaults": "^1.0.3" - } - }, "node_modules/npm/node_modules/which": { - "version": "4.0.0", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -9420,7 +9112,7 @@ "node-which": "bin/which.js" }, "engines": { - "node": "^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/which/node_modules/isexe": { @@ -9432,15 +9124,6 @@ "node": ">=16" } }, - "node_modules/npm/node_modules/wide-align": { - "version": "1.1.5", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, "node_modules/npm/node_modules/wrap-ansi": { "version": "8.1.0", "dev": true, @@ -9492,7 +9175,7 @@ } }, "node_modules/npm/node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.0.1", + "version": "6.1.0", "dev": true, "inBundle": true, "license": "MIT", @@ -9542,7 +9225,7 @@ } }, "node_modules/npm/node_modules/write-file-atomic": { - "version": "5.0.1", + "version": "6.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -9551,7 +9234,7 @@ "signal-exit": "^4.0.1" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/yallist": { @@ -9629,30 +9312,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/open": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/open/-/open-9.1.0.tgz", - "integrity": "sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==", - "dev": true, - "peer": true, - "dependencies": { - "default-browser": "^4.0.0", - "define-lazy-prop": "^3.0.0", - "is-inside-container": "^1.0.0", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, + "peer": true, "dependencies": { "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", @@ -9779,6 +9444,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, + "peer": true, "dependencies": { "yocto-queue": "^0.1.0" }, @@ -9794,6 +9460,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "peer": true, "dependencies": { "p-limit": "^3.0.2" }, @@ -9906,6 +9573,7 @@ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, + "peer": true, "engines": { "node": ">=8" } @@ -10123,6 +9791,7 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, + "peer": true, "engines": { "node": ">= 0.8.0" } @@ -10142,19 +9811,6 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dev": true, - "peer": true, - "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/prisma": { "version": "5.15.1", "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.15.1.tgz", @@ -10535,162 +10191,50 @@ "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", "dev": true, "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rollup": { - "version": "4.24.3", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.3.tgz", - "integrity": "sha512-HBW896xR5HGmoksbi3JBDtmVzWiPAYqp7wip50hjQ67JbDz61nyoMPdqu1DvVW9asYb2M65Z20ZHsyJCMqMyDg==", - "dev": true, - "dependencies": { - "@types/estree": "1.0.6" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.24.3", - "@rollup/rollup-android-arm64": "4.24.3", - "@rollup/rollup-darwin-arm64": "4.24.3", - "@rollup/rollup-darwin-x64": "4.24.3", - "@rollup/rollup-freebsd-arm64": "4.24.3", - "@rollup/rollup-freebsd-x64": "4.24.3", - "@rollup/rollup-linux-arm-gnueabihf": "4.24.3", - "@rollup/rollup-linux-arm-musleabihf": "4.24.3", - "@rollup/rollup-linux-arm64-gnu": "4.24.3", - "@rollup/rollup-linux-arm64-musl": "4.24.3", - "@rollup/rollup-linux-powerpc64le-gnu": "4.24.3", - "@rollup/rollup-linux-riscv64-gnu": "4.24.3", - "@rollup/rollup-linux-s390x-gnu": "4.24.3", - "@rollup/rollup-linux-x64-gnu": "4.24.3", - "@rollup/rollup-linux-x64-musl": "4.24.3", - "@rollup/rollup-win32-arm64-msvc": "4.24.3", - "@rollup/rollup-win32-ia32-msvc": "4.24.3", - "@rollup/rollup-win32-x64-msvc": "4.24.3", - "fsevents": "~2.3.2" - } - }, - "node_modules/run-applescript": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz", - "integrity": "sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==", - "dev": true, - "peer": true, - "dependencies": { - "execa": "^5.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/run-applescript/node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "peer": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/run-applescript/node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, - "peer": true, - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/run-applescript/node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/run-applescript/node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/run-applescript/node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "peer": true, - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/run-applescript/node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "peer": true, - "dependencies": { - "mimic-fn": "^2.1.0" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=6" + "node": ">=16 || 14 >=14.17" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/run-applescript/node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "node_modules/rollup": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.3.tgz", + "integrity": "sha512-HBW896xR5HGmoksbi3JBDtmVzWiPAYqp7wip50hjQ67JbDz61nyoMPdqu1DvVW9asYb2M65Z20ZHsyJCMqMyDg==", "dev": true, - "peer": true, + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, "engines": { - "node": ">=6" + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.24.3", + "@rollup/rollup-android-arm64": "4.24.3", + "@rollup/rollup-darwin-arm64": "4.24.3", + "@rollup/rollup-darwin-x64": "4.24.3", + "@rollup/rollup-freebsd-arm64": "4.24.3", + "@rollup/rollup-freebsd-x64": "4.24.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.24.3", + "@rollup/rollup-linux-arm-musleabihf": "4.24.3", + "@rollup/rollup-linux-arm64-gnu": "4.24.3", + "@rollup/rollup-linux-arm64-musl": "4.24.3", + "@rollup/rollup-linux-powerpc64le-gnu": "4.24.3", + "@rollup/rollup-linux-riscv64-gnu": "4.24.3", + "@rollup/rollup-linux-s390x-gnu": "4.24.3", + "@rollup/rollup-linux-x64-gnu": "4.24.3", + "@rollup/rollup-linux-x64-musl": "4.24.3", + "@rollup/rollup-win32-arm64-msvc": "4.24.3", + "@rollup/rollup-win32-ia32-msvc": "4.24.3", + "@rollup/rollup-win32-x64-msvc": "4.24.3", + "fsevents": "~2.3.2" } }, "node_modules/run-parallel": { @@ -11022,13 +10566,6 @@ "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true, - "peer": true - }, "node_modules/signale": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/signale/-/signale-1.4.0.tgz", @@ -11138,16 +10675,6 @@ "node": ">=8" } }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, "node_modules/slice-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", @@ -11413,6 +10940,7 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "peer": true, "engines": { "node": ">=8" }, @@ -11457,23 +10985,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/synckit": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.5.tgz", - "integrity": "sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==", - "dev": true, - "peer": true, - "dependencies": { - "@pkgr/utils": "^2.3.1", - "tslib": "^2.5.0" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, "node_modules/table": { "version": "6.8.1", "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", @@ -11640,7 +11151,8 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true + "dev": true, + "peer": true }, "node_modules/thenify": { "version": "3.3.1", @@ -11724,19 +11236,6 @@ "node": ">=14.0.0" } }, - "node_modules/titleize": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz", - "integrity": "sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==", - "dev": true, - "peer": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -11768,13 +11267,12 @@ } }, "node_modules/ts-api-utils": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", - "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", + "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", "dev": true, - "peer": true, "engines": { - "node": ">=16.13.0" + "node": ">=16" }, "peerDependencies": { "typescript": ">=4.2.0" @@ -11895,6 +11393,7 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", "dev": true, + "optional": true, "peer": true }, "node_modules/tweetnacl": { @@ -11908,6 +11407,7 @@ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, + "peer": true, "dependencies": { "prelude-ls": "^1.2.1" }, @@ -11920,6 +11420,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, + "peer": true, "engines": { "node": ">=10" }, @@ -12062,9 +11563,9 @@ } }, "node_modules/typescript": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz", - "integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==", + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -12074,6 +11575,258 @@ "node": ">=14.17" } }, + "node_modules/typescript-eslint": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.16.0.tgz", + "integrity": "sha512-wDkVmlY6O2do4V+lZd0GtRfbtXbeD0q9WygwXXSJnC1xorE8eqyC2L1tJimqpSeFrOzRlYtWnUp/uzgHQOgfBQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.16.0", + "@typescript-eslint/parser": "8.16.0", + "@typescript-eslint/utils": "8.16.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.16.0.tgz", + "integrity": "sha512-5YTHKV8MYlyMI6BaEG7crQ9BhSc8RxzshOReKwZwRWN0+XvvTOm+L/UYLCYxFpfwYuAAqhxiq4yae0CMFwbL7Q==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.16.0", + "@typescript-eslint/type-utils": "8.16.0", + "@typescript-eslint/utils": "8.16.0", + "@typescript-eslint/visitor-keys": "8.16.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/parser": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.16.0.tgz", + "integrity": "sha512-D7DbgGFtsqIPIFMPJwCad9Gfi/hC0PWErRRHFnaCWoEDYi5tQUDiJCTmGUbBiLzjqAck4KcXt9Ayj0CNlIrF+w==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "8.16.0", + "@typescript-eslint/types": "8.16.0", + "@typescript-eslint/typescript-estree": "8.16.0", + "@typescript-eslint/visitor-keys": "8.16.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/scope-manager": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.16.0.tgz", + "integrity": "sha512-mwsZWubQvBki2t5565uxF0EYvG+FwdFb8bMtDuGQLdCCnGPrDEDvm1gtfynuKlnpzeBRqdFCkMf9jg1fnAK8sg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.16.0", + "@typescript-eslint/visitor-keys": "8.16.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/type-utils": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.16.0.tgz", + "integrity": "sha512-IqZHGG+g1XCWX9NyqnI/0CX5LL8/18awQqmkZSl2ynn8F76j579dByc0jhfVSnSnhf7zv76mKBQv9HQFKvDCgg==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "8.16.0", + "@typescript-eslint/utils": "8.16.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/types": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.16.0.tgz", + "integrity": "sha512-NzrHj6thBAOSE4d9bsuRNMvk+BvaQvmY4dDglgkgGC0EW/tB3Kelnp3tAKH87GEwzoxgeQn9fNGRyFJM/xd+GQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.16.0.tgz", + "integrity": "sha512-E2+9IzzXMc1iaBy9zmo+UYvluE3TW7bCGWSF41hVWUE01o8nzr1rvOQYSxelxr6StUvRcTMe633eY8mXASMaNw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.16.0", + "@typescript-eslint/visitor-keys": "8.16.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/utils": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.16.0.tgz", + "integrity": "sha512-C1zRy/mOL8Pj157GiX4kaw7iyRLKfJXBR3L82hk5kS/GyHcOFmy4YUq/zfZti72I9wnuQtA/+xzft4wCC8PJdA==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.16.0", + "@typescript-eslint/types": "8.16.0", + "@typescript-eslint/typescript-estree": "8.16.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.16.0.tgz", + "integrity": "sha512-pq19gbaMOmFE3CbL0ZB8J8BFCo2ckfHBfaIsaOZgBIF4EoISJIdLX5xRhd0FGB0LlHReNRuzoJoMGpTjq8F2CQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.16.0", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/typescript-eslint/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/typescript-eslint/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/typescript-eslint/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/uglify-js": { "version": "3.17.4", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", @@ -12159,16 +11912,6 @@ "node": ">= 10.0.0" } }, - "node_modules/untildify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", - "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -12550,6 +12293,7 @@ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, + "peer": true, "engines": { "node": ">=10" }, diff --git a/package.json b/package.json index 1282919..f99d76b 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,8 @@ "build:3-copy-readme": "cpy README.md dist", "test": "vitest run --coverage --passWithNoTests", "test:watch": "vitest watch --coverage --passWithNoTests", - "lint": "eslint ./src/ --ext .ts", - "lint:fix": "eslint ./src/ --ext .ts --fix", + "lint": "eslint \"src/**/*.ts\"", + "lint:fix": "eslint \"src/**/*.ts\" --fix", "check-types": "tsc --noEmit", "audit": "better-npm-audit audit", "format": "prettier --write .", @@ -66,11 +66,12 @@ "./package.json": "./package.json" }, "devDependencies": { - "@prisma/client": "^5.15.1", + "@algorandfoundation/algokit-client-generator": "^4.0.2", "@commitlint/cli": "^19.2.1", "@commitlint/config-conventional": "^19.1.0", - "@makerx/eslint-config": "^3.1.1", + "@eslint/js": "^9.16.0", "@makerx/prettier-config": "^2.0.1", + "@prisma/client": "^5.15.1", "@rollup/plugin-typescript": "^11.1.6", "@vitest/coverage-v8": "^2.1.4", "better-npm-audit": "^3.7.3", @@ -78,7 +79,7 @@ "cpy-cli": "^5.0.0", "cross-env": "^7.0.3", "dotenv-cli": "^7.4.1", - "eslint": "8.57.0", + "eslint-config-prettier": "^9.1.0", "npm-run-all": "^4.1.5", "prettier": "3.2.5", "prisma": "^5.15.1", @@ -90,6 +91,7 @@ "typedoc": "^0.25.4", "typedoc-plugin-markdown": "^3.17.1", "typescript": "^5.4.3", + "typescript-eslint": "^8.16.0", "vitest": "^2.1.4" }, "dependencies": { @@ -99,8 +101,8 @@ "js-sha512": "^0.9.0" }, "peerDependencies": { - "@algorandfoundation/algokit-utils": "^6.1.0", - "algosdk": "^2.7.0" + "@algorandfoundation/algokit-utils": "^7.0.0", + "algosdk": ">=2.9.0 <3.0" }, "publishConfig": { "access": "public" diff --git a/src/subscriber.ts b/src/subscriber.ts index 815778e..770cde4 100644 --- a/src/subscriber.ts +++ b/src/subscriber.ts @@ -1,4 +1,4 @@ -import * as algokit from '@algorandfoundation/algokit-utils' +import { Config } from '@algorandfoundation/algokit-utils' import algosdk from 'algosdk' import { getSubscribedTransactions } from './subscriptions' import { AsyncEventEmitter, AsyncEventListener } from './types/async-event-emitter' @@ -96,7 +96,7 @@ export class AlgorandSubscriber { } await this.eventEmitter.emitAsync('poll', pollResult) } catch (e) { - algokit.Config.logger.error(`Error processing event emittance`, e) + Config.logger.error(`Error processing event emittance`, e) throw e } await this.config.watermarkPersistence.set(pollResult.newWatermark) @@ -122,7 +122,7 @@ export class AlgorandSubscriber { const start = +new Date() const result = await this.pollOnce() const durationInSeconds = (+new Date() - start) / 1000 - algokit.Config.getLogger(suppressLog).debug('Subscription poll', { + Config.getLogger(suppressLog).debug('Subscription poll', { currentRound: result.currentRound, startingWatermark: result.startingWatermark, newWatermark: result.newWatermark, @@ -132,13 +132,13 @@ export class AlgorandSubscriber { inspect?.(result) // eslint-disable-next-line no-console if (result.currentRound > result.newWatermark || !this.config.waitForBlockWhenAtTip) { - algokit.Config.getLogger(suppressLog).info( + Config.getLogger(suppressLog).info( `Subscription poll completed in ${durationInSeconds}s; sleeping for ${this.config.frequencyInSeconds ?? 1}s`, ) await sleep((this.config.frequencyInSeconds ?? 1) * 1000, this.abortController.signal) } else { // Wait until the next block is published - algokit.Config.getLogger(suppressLog).info( + Config.getLogger(suppressLog).info( `Subscription poll completed in ${durationInSeconds}s; waiting for round ${result.currentRound + 1}`, ) const waitStart = +new Date() @@ -146,7 +146,7 @@ export class AlgorandSubscriber { // the round you are waiting for per the API description: // https://developer.algorand.org/docs/rest-apis/algod/#get-v2statuswait-for-block-afterround await race(this.algod.statusAfterBlock(result.currentRound).do(), this.abortController.signal) - algokit.Config.getLogger(suppressLog).info(`Waited for ${(+new Date() - waitStart) / 1000}s until next block`) + Config.getLogger(suppressLog).info(`Waited for ${(+new Date() - waitStart) / 1000}s until next block`) } } this.started = false diff --git a/src/subscriptions.ts b/src/subscriptions.ts index 0a684e9..6b99422 100644 --- a/src/subscriptions.ts +++ b/src/subscriptions.ts @@ -1,6 +1,5 @@ -import * as algokit from '@algorandfoundation/algokit-utils' +import { Config, searchTransactions } from '@algorandfoundation/algokit-utils' import type { TransactionResult } from '@algorandfoundation/algokit-utils/types/indexer' - import algosdk from 'algosdk' import type SearchForTransactions from 'algosdk/dist/types/client/v2/indexer/searchForTransactions' import { Buffer } from 'buffer' @@ -139,7 +138,7 @@ export async function getSubscribedTransactions( algodSyncFromRoundNumber = indexerSyncToRoundNumber + 1 } - algokit.Config.logger.debug( + Config.logger.debug( `Catching up from round ${startRound} to round ${indexerSyncToRoundNumber} via indexer; this may take a few seconds`, ) @@ -151,7 +150,7 @@ export async function getSubscribedTransactions( // For each filter chunkedFilters.map(async (f) => // Retrieve all pre-filtered transactions from the indexer - (await algokit.searchTransactions(indexer, indexerPreFilter(f.filter, startRound, indexerSyncToRoundNumber))).transactions + (await searchTransactions(indexer, indexerPreFilter(f.filter, startRound, indexerSyncToRoundNumber))).transactions // Re-run the pre-filter in-memory so we properly extract inner transactions .flatMap((t) => getFilteredIndexerTransactions(t, f)) // Run the post-filter so we get the final list of matching transactions @@ -170,7 +169,7 @@ export async function getSubscribedTransactions( // Collapse duplicate transactions .reduce(deduplicateSubscribedTransactionsReducer, [] as SubscribedTransaction[]) - algokit.Config.logger.debug( + Config.logger.debug( `Retrieved ${catchupTransactions.length} transactions from round ${startRound} to round ${ algodSyncFromRoundNumber - 1 } via indexer in ${(+new Date() - start) / 1000}s`, @@ -198,15 +197,13 @@ export async function getSubscribedTransactions( blockMetadata = blocks.map((b) => blockDataToBlockMetadata(b)) - algokit.Config.logger.debug( + Config.logger.debug( `Retrieved ${blockTransactions.length} transactions from algod via round(s) ${algodSyncFromRoundNumber}-${endRound} in ${ (+new Date() - start) / 1000 }s`, ) } else { - algokit.Config.logger.debug( - `Skipping algod sync since we have more than ${subscription.maxIndexerRoundsToSync} rounds to sync from indexer.`, - ) + Config.logger.debug(`Skipping algod sync since we have more than ${subscription.maxIndexerRoundsToSync} rounds to sync from indexer.`) } return { @@ -434,10 +431,10 @@ function indexerPreFilterInMemory(subscription: TransactionFilter): (t: Transact if (subscription.assetId) { if (typeof subscription.assetId === 'number' || typeof subscription.assetId === 'bigint') { result &&= - t['created-asset-index'] === subscription.assetId || - (!!t['asset-config-transaction'] && t['asset-config-transaction']['asset-id'] === subscription.assetId) || - (!!t['asset-freeze-transaction'] && t['asset-freeze-transaction']['asset-id'] === subscription.assetId) || - (!!t['asset-transfer-transaction'] && t['asset-transfer-transaction']['asset-id'] === subscription.assetId) + t['created-asset-index'] === Number(subscription.assetId) || + (!!t['asset-config-transaction'] && t['asset-config-transaction']['asset-id'] === Number(subscription.assetId)) || + (!!t['asset-freeze-transaction'] && t['asset-freeze-transaction']['asset-id'] === Number(subscription.assetId)) || + (!!t['asset-transfer-transaction'] && t['asset-transfer-transaction']['asset-id'] === Number(subscription.assetId)) } else { result &&= (t['created-asset-index'] && subscription.assetId.map((i) => Number(i)).includes(t['created-asset-index'])) || @@ -584,7 +581,7 @@ function transactionFilter( } if (subscription.assetId) { if (typeof subscription.assetId === 'number' || typeof subscription.assetId === 'bigint') { - result &&= t.assetIndex === subscription.assetId || createdAssetId === subscription.assetId + result &&= t.assetIndex === Number(subscription.assetId) || createdAssetId === Number(subscription.assetId) } else { result &&= (!!t.assetIndex && subscription.assetId.map((i) => Number(i)).includes(t.assetIndex)) || @@ -661,7 +658,9 @@ function hasBalanceChangeMatch(transactionBalanceChanges: BalanceChange[], filte (changeFilter.maxAmount === undefined || actualChange.amount <= changeFilter.maxAmount) && (changeFilter.assetId === undefined || (Array.isArray(changeFilter.assetId) && changeFilter.assetId.length === 0) || - (Array.isArray(changeFilter.assetId) ? changeFilter.assetId : [changeFilter.assetId]).includes(actualChange.assetId)) && + (Array.isArray(changeFilter.assetId) ? changeFilter.assetId : [changeFilter.assetId]) + .map((a) => Number(a)) + .includes(actualChange.assetId)) && (changeFilter.role === undefined || (Array.isArray(changeFilter.role) && changeFilter.role.length === 0) || (Array.isArray(changeFilter.role) ? changeFilter.role : [changeFilter.role]).some((r) => actualChange.roles.includes(r))), diff --git a/tests/contract/client.ts b/tests/contract/client.ts index 18b5452..db1c268 100644 --- a/tests/contract/client.ts +++ b/tests/contract/client.ts @@ -2,687 +2,328 @@ /** * This file was automatically generated by @algorandfoundation/algokit-client-generator. * DO NOT MODIFY IT BY HAND. - * requires: @algorandfoundation/algokit-utils: ^2 + * requires: @algorandfoundation/algokit-utils: ^7 */ -import * as algokit from '@algorandfoundation/algokit-utils' -import type { - ABIAppCallArg, - AppCallTransactionResult, - AppCallTransactionResultOfType, - AppCompilationResult, - AppReference, - AppState, - CoreAppCallArgs, - RawAppCallArgs, - TealTemplateParams, -} from '@algorandfoundation/algokit-utils/types/app' -import type { - AppClientCallCoreParams, +import { AlgorandClientInterface } from '@algorandfoundation/algokit-utils/types/algorand-client-interface' +import { ABIReturn, AppReturn, SendAppTransactionResult } from '@algorandfoundation/algokit-utils/types/app' +import { Arc56Contract, getArc56ReturnValue, getABIStructFromABITuple } from '@algorandfoundation/algokit-utils/types/app-arc56' +import { + AppClient as _AppClient, + AppClientMethodCallParams, + AppClientParams, + AppClientBareCallParams, + CallOnComplete, AppClientCompilationParams, - AppClientDeployCoreParams, - AppDetails, - ApplicationClient, + ResolveAppClientByCreatorAndName, + ResolveAppClientByNetwork, + CloneAppClientParams, } from '@algorandfoundation/algokit-utils/types/app-client' -import type { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' -import type { SendTransactionResult, TransactionToSign, SendTransactionFrom } from '@algorandfoundation/algokit-utils/types/transaction' -import type { ABIResult, TransactionWithSigner } from 'algosdk' -import { Algodv2, OnApplicationComplete, Transaction, AtomicTransactionComposer, modelsv2 } from 'algosdk' -export const APP_SPEC: AppSpec = { - hints: { - 'call_abi(string)string': { - read_only: true, - call_config: { - no_op: 'CALL', - }, - }, - 'call_abi_foreign_refs()string': { - read_only: true, - call_config: { - no_op: 'CALL', - }, - }, - 'set_global(uint64,uint64,string,byte[4])void': { - call_config: { - no_op: 'CALL', - }, - }, - 'set_local(uint64,uint64,string,byte[4])void': { - call_config: { - no_op: 'CALL', - }, - }, - 'issue_transfer_to_sender(uint64)void': { - call_config: { - no_op: 'CALL', - }, - }, - 'set_box(byte[4],string)void': { - call_config: { - no_op: 'CALL', - }, - }, - 'error()void': { - call_config: { - no_op: 'CALL', - }, - }, - 'opt_in()void': { - call_config: { - opt_in: 'CALL', - }, - }, - 'emitSwapped(uint64,uint64)void': { - call_config: { - no_op: 'CALL', - }, - }, - 'emitSwappedTwice(uint64,uint64)void': { - call_config: { - no_op: 'CALL', - }, - }, - 'emitComplex(uint64,uint64,uint32[])void': { - call_config: { - no_op: 'CALL', - }, - }, - }, - source: { - approval: - 'I3ByYWdtYSB2ZXJzaW9uIDgKaW50Y2Jsb2NrIDAgMSAxMApieXRlY2Jsb2NrIDB4IDB4MWNjYmQ5MjUgMHgxNTFmN2M3NQp0eG4gTnVtQXBwQXJncwppbnRjXzAgLy8gMAo9PQpibnogbWFpbl9sMjQKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMApwdXNoYnl0ZXMgMHhmMTdlODBhNSAvLyAiY2FsbF9hYmkoc3RyaW5nKXN0cmluZyIKPT0KYm56IG1haW5fbDIzCnR4bmEgQXBwbGljYXRpb25BcmdzIDAKcHVzaGJ5dGVzIDB4YWQ3NTYwMmMgLy8gImNhbGxfYWJpX2ZvcmVpZ25fcmVmcygpc3RyaW5nIgo9PQpibnogbWFpbl9sMjIKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMApwdXNoYnl0ZXMgMHhhNGNmOGRlYSAvLyAic2V0X2dsb2JhbCh1aW50NjQsdWludDY0LHN0cmluZyxieXRlWzRdKXZvaWQiCj09CmJueiBtYWluX2wyMQp0eG5hIEFwcGxpY2F0aW9uQXJncyAwCnB1c2hieXRlcyAweGNlYzI4MzRhIC8vICJzZXRfbG9jYWwodWludDY0LHVpbnQ2NCxzdHJpbmcsYnl0ZVs0XSl2b2lkIgo9PQpibnogbWFpbl9sMjAKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMApwdXNoYnl0ZXMgMHg5OGJlMjIxOSAvLyAiaXNzdWVfdHJhbnNmZXJfdG9fc2VuZGVyKHVpbnQ2NCl2b2lkIgo9PQpibnogbWFpbl9sMTkKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMApwdXNoYnl0ZXMgMHhhNGI0YTIzMCAvLyAic2V0X2JveChieXRlWzRdLHN0cmluZyl2b2lkIgo9PQpibnogbWFpbl9sMTgKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMApwdXNoYnl0ZXMgMHg0NGQwZGEwZCAvLyAiZXJyb3IoKXZvaWQiCj09CmJueiBtYWluX2wxNwp0eG5hIEFwcGxpY2F0aW9uQXJncyAwCnB1c2hieXRlcyAweDMwYzZkNThhIC8vICJvcHRfaW4oKXZvaWQiCj09CmJueiBtYWluX2wxNgp0eG5hIEFwcGxpY2F0aW9uQXJncyAwCnB1c2hieXRlcyAweGQ0M2NlZTVkIC8vICJlbWl0U3dhcHBlZCh1aW50NjQsdWludDY0KXZvaWQiCj09CmJueiBtYWluX2wxNQp0eG5hIEFwcGxpY2F0aW9uQXJncyAwCnB1c2hieXRlcyAweDExYjA5NzVhIC8vICJlbWl0U3dhcHBlZFR3aWNlKHVpbnQ2NCx1aW50NjQpdm9pZCIKPT0KYm56IG1haW5fbDE0CnR4bmEgQXBwbGljYXRpb25BcmdzIDAKcHVzaGJ5dGVzIDB4YWQyMzBkMGMgLy8gImVtaXRDb21wbGV4KHVpbnQ2NCx1aW50NjQsdWludDMyW10pdm9pZCIKPT0KYm56IG1haW5fbDEzCmVycgptYWluX2wxMzoKdHhuIE9uQ29tcGxldGlvbgppbnRjXzAgLy8gTm9PcAo9PQp0eG4gQXBwbGljYXRpb25JRAppbnRjXzAgLy8gMAohPQomJgphc3NlcnQKY2FsbHN1YiBlbWl0Q29tcGxleGNhc3Rlcl8yNQppbnRjXzEgLy8gMQpyZXR1cm4KbWFpbl9sMTQ6CnR4biBPbkNvbXBsZXRpb24KaW50Y18wIC8vIE5vT3AKPT0KdHhuIEFwcGxpY2F0aW9uSUQKaW50Y18wIC8vIDAKIT0KJiYKYXNzZXJ0CmNhbGxzdWIgZW1pdFN3YXBwZWRUd2ljZWNhc3Rlcl8yNAppbnRjXzEgLy8gMQpyZXR1cm4KbWFpbl9sMTU6CnR4biBPbkNvbXBsZXRpb24KaW50Y18wIC8vIE5vT3AKPT0KdHhuIEFwcGxpY2F0aW9uSUQKaW50Y18wIC8vIDAKIT0KJiYKYXNzZXJ0CmNhbGxzdWIgZW1pdFN3YXBwZWRjYXN0ZXJfMjMKaW50Y18xIC8vIDEKcmV0dXJuCm1haW5fbDE2Ogp0eG4gT25Db21wbGV0aW9uCmludGNfMSAvLyBPcHRJbgo9PQp0eG4gQXBwbGljYXRpb25JRAppbnRjXzAgLy8gMAohPQomJgphc3NlcnQKY2FsbHN1YiBvcHRpbmNhc3Rlcl8yMgppbnRjXzEgLy8gMQpyZXR1cm4KbWFpbl9sMTc6CnR4biBPbkNvbXBsZXRpb24KaW50Y18wIC8vIE5vT3AKPT0KdHhuIEFwcGxpY2F0aW9uSUQKaW50Y18wIC8vIDAKIT0KJiYKYXNzZXJ0CmNhbGxzdWIgZXJyb3JjYXN0ZXJfMjEKaW50Y18xIC8vIDEKcmV0dXJuCm1haW5fbDE4Ogp0eG4gT25Db21wbGV0aW9uCmludGNfMCAvLyBOb09wCj09CnR4biBBcHBsaWNhdGlvbklECmludGNfMCAvLyAwCiE9CiYmCmFzc2VydApjYWxsc3ViIHNldGJveGNhc3Rlcl8yMAppbnRjXzEgLy8gMQpyZXR1cm4KbWFpbl9sMTk6CnR4biBPbkNvbXBsZXRpb24KaW50Y18wIC8vIE5vT3AKPT0KdHhuIEFwcGxpY2F0aW9uSUQKaW50Y18wIC8vIDAKIT0KJiYKYXNzZXJ0CmNhbGxzdWIgaXNzdWV0cmFuc2ZlcnRvc2VuZGVyY2FzdGVyXzE5CmludGNfMSAvLyAxCnJldHVybgptYWluX2wyMDoKdHhuIE9uQ29tcGxldGlvbgppbnRjXzAgLy8gTm9PcAo9PQp0eG4gQXBwbGljYXRpb25JRAppbnRjXzAgLy8gMAohPQomJgphc3NlcnQKY2FsbHN1YiBzZXRsb2NhbGNhc3Rlcl8xOAppbnRjXzEgLy8gMQpyZXR1cm4KbWFpbl9sMjE6CnR4biBPbkNvbXBsZXRpb24KaW50Y18wIC8vIE5vT3AKPT0KdHhuIEFwcGxpY2F0aW9uSUQKaW50Y18wIC8vIDAKIT0KJiYKYXNzZXJ0CmNhbGxzdWIgc2V0Z2xvYmFsY2FzdGVyXzE3CmludGNfMSAvLyAxCnJldHVybgptYWluX2wyMjoKdHhuIE9uQ29tcGxldGlvbgppbnRjXzAgLy8gTm9PcAo9PQp0eG4gQXBwbGljYXRpb25JRAppbnRjXzAgLy8gMAohPQomJgphc3NlcnQKY2FsbHN1YiBjYWxsYWJpZm9yZWlnbnJlZnNjYXN0ZXJfMTYKaW50Y18xIC8vIDEKcmV0dXJuCm1haW5fbDIzOgp0eG4gT25Db21wbGV0aW9uCmludGNfMCAvLyBOb09wCj09CnR4biBBcHBsaWNhdGlvbklECmludGNfMCAvLyAwCiE9CiYmCmFzc2VydApjYWxsc3ViIGNhbGxhYmljYXN0ZXJfMTUKaW50Y18xIC8vIDEKcmV0dXJuCm1haW5fbDI0Ogp0eG4gT25Db21wbGV0aW9uCmludGNfMCAvLyBOb09wCj09CmJueiBtYWluX2wzMgp0eG4gT25Db21wbGV0aW9uCmludGNfMSAvLyBPcHRJbgo9PQpibnogbWFpbl9sMzEKdHhuIE9uQ29tcGxldGlvbgpwdXNoaW50IDQgLy8gVXBkYXRlQXBwbGljYXRpb24KPT0KYm56IG1haW5fbDMwCnR4biBPbkNvbXBsZXRpb24KcHVzaGludCA1IC8vIERlbGV0ZUFwcGxpY2F0aW9uCj09CmJueiBtYWluX2wyOQplcnIKbWFpbl9sMjk6CnR4biBBcHBsaWNhdGlvbklECmludGNfMCAvLyAwCiE9CmFzc2VydApjYWxsc3ViIGRlbGV0ZV8xMAppbnRjXzEgLy8gMQpyZXR1cm4KbWFpbl9sMzA6CnR4biBBcHBsaWNhdGlvbklECmludGNfMCAvLyAwCiE9CmFzc2VydApjYWxsc3ViIHVwZGF0ZV85CmludGNfMSAvLyAxCnJldHVybgptYWluX2wzMToKdHhuIEFwcGxpY2F0aW9uSUQKaW50Y18wIC8vIDAKPT0KYXNzZXJ0CmNhbGxzdWIgY3JlYXRlXzgKaW50Y18xIC8vIDEKcmV0dXJuCm1haW5fbDMyOgp0eG4gQXBwbGljYXRpb25JRAppbnRjXzAgLy8gMAo9PQphc3NlcnQKY2FsbHN1YiBjcmVhdGVfOAppbnRjXzEgLy8gMQpyZXR1cm4KCi8vIGNhbGxfYWJpCmNhbGxhYmlfMDoKcHJvdG8gMSAxCmJ5dGVjXzAgLy8gIiIKcHVzaGJ5dGVzIDB4NDg2NTZjNmM2ZjJjMjAgLy8gIkhlbGxvLCAiCmZyYW1lX2RpZyAtMQpleHRyYWN0IDIgMApjb25jYXQKZnJhbWVfYnVyeSAwCmZyYW1lX2RpZyAwCmxlbgppdG9iCmV4dHJhY3QgNiAwCmZyYW1lX2RpZyAwCmNvbmNhdApmcmFtZV9idXJ5IDAKcmV0c3ViCgovLyBpdG9hCml0b2FfMToKcHJvdG8gMSAxCmZyYW1lX2RpZyAtMQppbnRjXzAgLy8gMAo9PQpibnogaXRvYV8xX2w1CmZyYW1lX2RpZyAtMQppbnRjXzIgLy8gMTAKLwppbnRjXzAgLy8gMAo+CmJueiBpdG9hXzFfbDQKYnl0ZWNfMCAvLyAiIgppdG9hXzFfbDM6CnB1c2hieXRlcyAweDMwMzEzMjMzMzQzNTM2MzczODM5IC8vICIwMTIzNDU2Nzg5IgpmcmFtZV9kaWcgLTEKaW50Y18yIC8vIDEwCiUKaW50Y18xIC8vIDEKZXh0cmFjdDMKY29uY2F0CmIgaXRvYV8xX2w2Cml0b2FfMV9sNDoKZnJhbWVfZGlnIC0xCmludGNfMiAvLyAxMAovCmNhbGxzdWIgaXRvYV8xCmIgaXRvYV8xX2wzCml0b2FfMV9sNToKcHVzaGJ5dGVzIDB4MzAgLy8gIjAiCml0b2FfMV9sNjoKcmV0c3ViCgovLyBjYWxsX2FiaV9mb3JlaWduX3JlZnMKY2FsbGFiaWZvcmVpZ25yZWZzXzI6CnByb3RvIDAgMQpieXRlY18wIC8vICIiCnB1c2hieXRlcyAweDQxNzA3MDNhMjAgLy8gIkFwcDogIgp0eG5hIEFwcGxpY2F0aW9ucyAxCmNhbGxzdWIgaXRvYV8xCmNvbmNhdApwdXNoYnl0ZXMgMHgyYzIwNDE3MzczNjU3NDNhMjAgLy8gIiwgQXNzZXQ6ICIKY29uY2F0CnR4bmEgQXNzZXRzIDAKY2FsbHN1YiBpdG9hXzEKY29uY2F0CnB1c2hieXRlcyAweDJjMjA0MTYzNjM2Zjc1NmU3NDNhMjAgLy8gIiwgQWNjb3VudDogIgpjb25jYXQKdHhuYSBBY2NvdW50cyAwCmludGNfMCAvLyAwCmdldGJ5dGUKY2FsbHN1YiBpdG9hXzEKY29uY2F0CnB1c2hieXRlcyAweDNhIC8vICI6Igpjb25jYXQKdHhuYSBBY2NvdW50cyAwCmludGNfMSAvLyAxCmdldGJ5dGUKY2FsbHN1YiBpdG9hXzEKY29uY2F0CmZyYW1lX2J1cnkgMApmcmFtZV9kaWcgMApsZW4KaXRvYgpleHRyYWN0IDYgMApmcmFtZV9kaWcgMApjb25jYXQKZnJhbWVfYnVyeSAwCnJldHN1YgoKLy8gc2V0X2dsb2JhbApzZXRnbG9iYWxfMzoKcHJvdG8gNCAwCnB1c2hieXRlcyAweDY5NmU3NDMxIC8vICJpbnQxIgpmcmFtZV9kaWcgLTQKYXBwX2dsb2JhbF9wdXQKcHVzaGJ5dGVzIDB4Njk2ZTc0MzIgLy8gImludDIiCmZyYW1lX2RpZyAtMwphcHBfZ2xvYmFsX3B1dApwdXNoYnl0ZXMgMHg2Mjc5NzQ2NTczMzEgLy8gImJ5dGVzMSIKZnJhbWVfZGlnIC0yCmV4dHJhY3QgMiAwCmFwcF9nbG9iYWxfcHV0CnB1c2hieXRlcyAweDYyNzk3NDY1NzMzMiAvLyAiYnl0ZXMyIgpmcmFtZV9kaWcgLTEKYXBwX2dsb2JhbF9wdXQKcmV0c3ViCgovLyBzZXRfbG9jYWwKc2V0bG9jYWxfNDoKcHJvdG8gNCAwCnR4biBTZW5kZXIKcHVzaGJ5dGVzIDB4NmM2ZjYzNjE2YzVmNjk2ZTc0MzEgLy8gImxvY2FsX2ludDEiCmZyYW1lX2RpZyAtNAphcHBfbG9jYWxfcHV0CnR4biBTZW5kZXIKcHVzaGJ5dGVzIDB4NmM2ZjYzNjE2YzVmNjk2ZTc0MzIgLy8gImxvY2FsX2ludDIiCmZyYW1lX2RpZyAtMwphcHBfbG9jYWxfcHV0CnR4biBTZW5kZXIKcHVzaGJ5dGVzIDB4NmM2ZjYzNjE2YzVmNjI3OTc0NjU3MzMxIC8vICJsb2NhbF9ieXRlczEiCmZyYW1lX2RpZyAtMgpleHRyYWN0IDIgMAphcHBfbG9jYWxfcHV0CnR4biBTZW5kZXIKcHVzaGJ5dGVzIDB4NmM2ZjYzNjE2YzVmNjI3OTc0NjU3MzMyIC8vICJsb2NhbF9ieXRlczIiCmZyYW1lX2RpZyAtMQphcHBfbG9jYWxfcHV0CnJldHN1YgoKLy8gaXNzdWVfdHJhbnNmZXJfdG9fc2VuZGVyCmlzc3VldHJhbnNmZXJ0b3NlbmRlcl81Ogpwcm90byAxIDAKaXR4bl9iZWdpbgppbnRjXzEgLy8gcGF5Cml0eG5fZmllbGQgVHlwZUVudW0KZnJhbWVfZGlnIC0xCml0eG5fZmllbGQgQW1vdW50CnR4biBTZW5kZXIKaXR4bl9maWVsZCBSZWNlaXZlcgppbnRjXzAgLy8gMAppdHhuX2ZpZWxkIEZlZQppdHhuX3N1Ym1pdApyZXRzdWIKCi8vIHNldF9ib3gKc2V0Ym94XzY6CnByb3RvIDIgMApmcmFtZV9kaWcgLTIKYm94X2RlbApwb3AKZnJhbWVfZGlnIC0yCmZyYW1lX2RpZyAtMQpleHRyYWN0IDIgMApib3hfcHV0CnJldHN1YgoKLy8gZXJyb3IKZXJyb3JfNzoKcHJvdG8gMCAwCmludGNfMCAvLyAwCi8vIERlbGliZXJhdGUgZXJyb3IKYXNzZXJ0CnJldHN1YgoKLy8gY3JlYXRlCmNyZWF0ZV84Ogpwcm90byAwIDAKaW50Y18xIC8vIDEKcmV0dXJuCgovLyB1cGRhdGUKdXBkYXRlXzk6CnByb3RvIDAgMAp0eG4gU2VuZGVyCmdsb2JhbCBDcmVhdG9yQWRkcmVzcwo9PQovLyB1bmF1dGhvcml6ZWQKYXNzZXJ0CmludGNfMSAvLyAxCnJldHVybgoKLy8gZGVsZXRlCmRlbGV0ZV8xMDoKcHJvdG8gMCAwCnR4biBTZW5kZXIKZ2xvYmFsIENyZWF0b3JBZGRyZXNzCj09Ci8vIHVuYXV0aG9yaXplZAphc3NlcnQKaW50Y18xIC8vIDEKcmV0dXJuCgovLyBvcHRfaW4Kb3B0aW5fMTE6CnByb3RvIDAgMAppbnRjXzEgLy8gMQpyZXR1cm4KCi8vIGVtaXRTd2FwcGVkCmVtaXRTd2FwcGVkXzEyOgpwcm90byAyIDAKYnl0ZWNfMSAvLyAiU3dhcHBlZCh1aW50NjQsdWludDY0KSIKZnJhbWVfZGlnIC0yCml0b2IKY29uY2F0CmZyYW1lX2RpZyAtMQppdG9iCmNvbmNhdApsb2cKaW50Y18xIC8vIDEKcmV0dXJuCgovLyBlbWl0U3dhcHBlZFR3aWNlCmVtaXRTd2FwcGVkVHdpY2VfMTM6CnByb3RvIDIgMApieXRlY18xIC8vICJTd2FwcGVkKHVpbnQ2NCx1aW50NjQpIgpmcmFtZV9kaWcgLTIKaXRvYgpjb25jYXQKZnJhbWVfZGlnIC0xCml0b2IKY29uY2F0CmxvZwpieXRlY18xIC8vICJTd2FwcGVkKHVpbnQ2NCx1aW50NjQpIgpmcmFtZV9kaWcgLTEKaXRvYgpjb25jYXQKZnJhbWVfZGlnIC0yCml0b2IKY29uY2F0CmxvZwppbnRjXzEgLy8gMQpyZXR1cm4KCi8vIGVtaXRDb21wbGV4CmVtaXRDb21wbGV4XzE0Ogpwcm90byAzIDAKYnl0ZWNfMCAvLyAiIgppbnRjXzAgLy8gMApkdXAKYnl0ZWNfMCAvLyAiIgpkdXAKZnJhbWVfZGlnIC0xCmZyYW1lX2J1cnkgNApmcmFtZV9kaWcgNApmcmFtZV9idXJ5IDMKaW50Y18yIC8vIDEwCmZyYW1lX2J1cnkgMQpmcmFtZV9kaWcgMQppdG9iCmV4dHJhY3QgNiAwCmZyYW1lX2RpZyAtMgppdG9iCmNvbmNhdApmcmFtZV9kaWcgMwpjb25jYXQKZnJhbWVfYnVyeSAwCmJ5dGVjXzEgLy8gIlN3YXBwZWQodWludDY0LHVpbnQ2NCkiCmZyYW1lX2RpZyAtMwppdG9iCmNvbmNhdApmcmFtZV9kaWcgLTIKaXRvYgpjb25jYXQKbG9nCnB1c2hieXRlcyAweDE4ZGE1ZWE3IC8vICJDb21wbGV4KHVpbnQzMltdLHVpbnQ2NCkiCmZyYW1lX2RpZyAwCmNvbmNhdApsb2cKaW50Y18xIC8vIDEKcmV0dXJuCgovLyBjYWxsX2FiaV9jYXN0ZXIKY2FsbGFiaWNhc3Rlcl8xNToKcHJvdG8gMCAwCmJ5dGVjXzAgLy8gIiIKZHVwCnR4bmEgQXBwbGljYXRpb25BcmdzIDEKZnJhbWVfYnVyeSAxCmZyYW1lX2RpZyAxCmNhbGxzdWIgY2FsbGFiaV8wCmZyYW1lX2J1cnkgMApieXRlY18yIC8vIDB4MTUxZjdjNzUKZnJhbWVfZGlnIDAKY29uY2F0CmxvZwpyZXRzdWIKCi8vIGNhbGxfYWJpX2ZvcmVpZ25fcmVmc19jYXN0ZXIKY2FsbGFiaWZvcmVpZ25yZWZzY2FzdGVyXzE2Ogpwcm90byAwIDAKYnl0ZWNfMCAvLyAiIgpjYWxsc3ViIGNhbGxhYmlmb3JlaWducmVmc18yCmZyYW1lX2J1cnkgMApieXRlY18yIC8vIDB4MTUxZjdjNzUKZnJhbWVfZGlnIDAKY29uY2F0CmxvZwpyZXRzdWIKCi8vIHNldF9nbG9iYWxfY2FzdGVyCnNldGdsb2JhbGNhc3Rlcl8xNzoKcHJvdG8gMCAwCmludGNfMCAvLyAwCmR1cApieXRlY18wIC8vICIiCmR1cAp0eG5hIEFwcGxpY2F0aW9uQXJncyAxCmJ0b2kKZnJhbWVfYnVyeSAwCnR4bmEgQXBwbGljYXRpb25BcmdzIDIKYnRvaQpmcmFtZV9idXJ5IDEKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwpmcmFtZV9idXJ5IDIKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNApmcmFtZV9idXJ5IDMKZnJhbWVfZGlnIDAKZnJhbWVfZGlnIDEKZnJhbWVfZGlnIDIKZnJhbWVfZGlnIDMKY2FsbHN1YiBzZXRnbG9iYWxfMwpyZXRzdWIKCi8vIHNldF9sb2NhbF9jYXN0ZXIKc2V0bG9jYWxjYXN0ZXJfMTg6CnByb3RvIDAgMAppbnRjXzAgLy8gMApkdXAKYnl0ZWNfMCAvLyAiIgpkdXAKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQpidG9pCmZyYW1lX2J1cnkgMAp0eG5hIEFwcGxpY2F0aW9uQXJncyAyCmJ0b2kKZnJhbWVfYnVyeSAxCnR4bmEgQXBwbGljYXRpb25BcmdzIDMKZnJhbWVfYnVyeSAyCnR4bmEgQXBwbGljYXRpb25BcmdzIDQKZnJhbWVfYnVyeSAzCmZyYW1lX2RpZyAwCmZyYW1lX2RpZyAxCmZyYW1lX2RpZyAyCmZyYW1lX2RpZyAzCmNhbGxzdWIgc2V0bG9jYWxfNApyZXRzdWIKCi8vIGlzc3VlX3RyYW5zZmVyX3RvX3NlbmRlcl9jYXN0ZXIKaXNzdWV0cmFuc2ZlcnRvc2VuZGVyY2FzdGVyXzE5Ogpwcm90byAwIDAKaW50Y18wIC8vIDAKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQpidG9pCmZyYW1lX2J1cnkgMApmcmFtZV9kaWcgMApjYWxsc3ViIGlzc3VldHJhbnNmZXJ0b3NlbmRlcl81CnJldHN1YgoKLy8gc2V0X2JveF9jYXN0ZXIKc2V0Ym94Y2FzdGVyXzIwOgpwcm90byAwIDAKYnl0ZWNfMCAvLyAiIgpkdXAKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQpmcmFtZV9idXJ5IDAKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgpmcmFtZV9idXJ5IDEKZnJhbWVfZGlnIDAKZnJhbWVfZGlnIDEKY2FsbHN1YiBzZXRib3hfNgpyZXRzdWIKCi8vIGVycm9yX2Nhc3RlcgplcnJvcmNhc3Rlcl8yMToKcHJvdG8gMCAwCmNhbGxzdWIgZXJyb3JfNwpyZXRzdWIKCi8vIG9wdF9pbl9jYXN0ZXIKb3B0aW5jYXN0ZXJfMjI6CnByb3RvIDAgMApjYWxsc3ViIG9wdGluXzExCnJldHN1YgoKLy8gZW1pdFN3YXBwZWRfY2FzdGVyCmVtaXRTd2FwcGVkY2FzdGVyXzIzOgpwcm90byAwIDAKaW50Y18wIC8vIDAKZHVwCnR4bmEgQXBwbGljYXRpb25BcmdzIDEKYnRvaQpmcmFtZV9idXJ5IDAKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgpidG9pCmZyYW1lX2J1cnkgMQpmcmFtZV9kaWcgMApmcmFtZV9kaWcgMQpjYWxsc3ViIGVtaXRTd2FwcGVkXzEyCnJldHN1YgoKLy8gZW1pdFN3YXBwZWRUd2ljZV9jYXN0ZXIKZW1pdFN3YXBwZWRUd2ljZWNhc3Rlcl8yNDoKcHJvdG8gMCAwCmludGNfMCAvLyAwCmR1cAp0eG5hIEFwcGxpY2F0aW9uQXJncyAxCmJ0b2kKZnJhbWVfYnVyeSAwCnR4bmEgQXBwbGljYXRpb25BcmdzIDIKYnRvaQpmcmFtZV9idXJ5IDEKZnJhbWVfZGlnIDAKZnJhbWVfZGlnIDEKY2FsbHN1YiBlbWl0U3dhcHBlZFR3aWNlXzEzCnJldHN1YgoKLy8gZW1pdENvbXBsZXhfY2FzdGVyCmVtaXRDb21wbGV4Y2FzdGVyXzI1Ogpwcm90byAwIDAKaW50Y18wIC8vIDAKZHVwCmJ5dGVjXzAgLy8gIiIKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQpidG9pCmZyYW1lX2J1cnkgMAp0eG5hIEFwcGxpY2F0aW9uQXJncyAyCmJ0b2kKZnJhbWVfYnVyeSAxCnR4bmEgQXBwbGljYXRpb25BcmdzIDMKZnJhbWVfYnVyeSAyCmZyYW1lX2RpZyAwCmZyYW1lX2RpZyAxCmZyYW1lX2RpZyAyCmNhbGxzdWIgZW1pdENvbXBsZXhfMTQKcmV0c3Vi', - clear: 'I3ByYWdtYSB2ZXJzaW9uIDgKcHVzaGludCAwIC8vIDAKcmV0dXJu', - }, - state: { - global: { - num_byte_slices: 2, - num_uints: 3, - }, - local: { - num_byte_slices: 2, - num_uints: 2, - }, - }, - schema: { - global: { - declared: { - bytes1: { - type: 'bytes', - key: 'bytes1', - descr: '', - }, - bytes2: { - type: 'bytes', - key: 'bytes2', - descr: '', - }, - int1: { - type: 'uint64', - key: 'int1', - descr: '', - }, - int2: { - type: 'uint64', - key: 'int2', - descr: '', - }, - value: { - type: 'uint64', - key: 'value', - descr: '', - }, - }, - reserved: {}, - }, - local: { - declared: { - local_bytes1: { - type: 'bytes', - key: 'local_bytes1', - descr: '', - }, - local_bytes2: { - type: 'bytes', - key: 'local_bytes2', - descr: '', - }, - local_int1: { - type: 'uint64', - key: 'local_int1', - descr: '', - }, - local_int2: { - type: 'uint64', - key: 'local_int2', - descr: '', - }, - }, - reserved: {}, - }, - }, - contract: { - name: 'TestingApp', - methods: [ - { - name: 'call_abi', - args: [ - { - type: 'string', - name: 'value', - }, - ], - returns: { - type: 'string', - }, - }, - { - name: 'call_abi_foreign_refs', - args: [], - returns: { - type: 'string', - }, - }, - { - name: 'set_global', - args: [ - { - type: 'uint64', - name: 'int1', - }, - { - type: 'uint64', - name: 'int2', - }, - { - type: 'string', - name: 'bytes1', - }, - { - type: 'byte[4]', - name: 'bytes2', - }, - ], - returns: { - type: 'void', - }, - }, - { - name: 'set_local', - args: [ - { - type: 'uint64', - name: 'int1', - }, - { - type: 'uint64', - name: 'int2', - }, - { - type: 'string', - name: 'bytes1', - }, - { - type: 'byte[4]', - name: 'bytes2', - }, - ], - returns: { - type: 'void', - }, - }, - { - name: 'issue_transfer_to_sender', - args: [ - { - type: 'uint64', - name: 'amount', - }, - ], - returns: { - type: 'void', - }, - }, - { - name: 'set_box', - args: [ - { - type: 'byte[4]', - name: 'name', - }, - { - type: 'string', - name: 'value', - }, - ], - returns: { - type: 'void', - }, - }, - { - name: 'error', - args: [], - returns: { - type: 'void', - }, - }, - { - name: 'opt_in', - args: [], - returns: { - type: 'void', - }, - }, - { - name: 'emitSwapped', - args: [ - { - type: 'uint64', - name: 'a', - }, - { - type: 'uint64', - name: 'b', - }, - ], - returns: { - type: 'void', - }, - }, - { - name: 'emitSwappedTwice', - args: [ - { - type: 'uint64', - name: 'a', - }, - { - type: 'uint64', - name: 'b', - }, - ], - returns: { - type: 'void', - }, - }, - { - name: 'emitComplex', - args: [ - { - type: 'uint64', - name: 'a', - }, - { - type: 'uint64', - name: 'b', - }, - { - type: 'uint32[]', - name: 'array', - }, - ], - returns: { - type: 'void', - }, - }, - ], - networks: {}, - }, - bare_call_config: { - delete_application: 'CALL', - no_op: 'CREATE', - opt_in: 'CREATE', - update_application: 'CALL', - }, -} +import { AppFactory as _AppFactory, AppFactoryAppClientParams, AppFactoryResolveAppClientByCreatorAndNameParams, AppFactoryDeployParams, AppFactoryParams, CreateSchema } from '@algorandfoundation/algokit-utils/types/app-factory' +import { TransactionComposer, AppCallMethodCall, AppMethodCallTransactionArgument, SimulateOptions } from '@algorandfoundation/algokit-utils/types/composer' +import { SendParams, SendSingleTransactionResult, SendAtomicTransactionComposerResults } from '@algorandfoundation/algokit-utils/types/transaction' +import { Address, encodeAddress, modelsv2, OnApplicationComplete, Transaction, TransactionSigner } from 'algosdk' +import SimulateResponse = modelsv2.SimulateResponse + +export const APP_SPEC: Arc56Contract = {"arcs":[],"name":"TestingApp","structs":{},"methods":[{"name":"call_abi","args":[{"name":"value","type":"string"}],"returns":{"type":"string"},"events":[],"readonly":true,"actions":{"create":[],"call":["NoOp"]}},{"name":"call_abi_foreign_refs","args":[],"returns":{"type":"string"},"events":[],"readonly":true,"actions":{"create":[],"call":["NoOp"]}},{"name":"set_global","args":[{"name":"int1","type":"uint64"},{"name":"int2","type":"uint64"},{"name":"bytes1","type":"string"},{"name":"bytes2","type":"byte[4]"}],"returns":{"type":"void"},"events":[],"actions":{"create":[],"call":["NoOp"]}},{"name":"set_local","args":[{"name":"int1","type":"uint64"},{"name":"int2","type":"uint64"},{"name":"bytes1","type":"string"},{"name":"bytes2","type":"byte[4]"}],"returns":{"type":"void"},"events":[],"actions":{"create":[],"call":["NoOp"]}},{"name":"issue_transfer_to_sender","args":[{"name":"amount","type":"uint64"}],"returns":{"type":"void"},"events":[],"actions":{"create":[],"call":["NoOp"]}},{"name":"set_box","args":[{"name":"name","type":"byte[4]"},{"name":"value","type":"string"}],"returns":{"type":"void"},"events":[],"actions":{"create":[],"call":["NoOp"]}},{"name":"error","args":[],"returns":{"type":"void"},"events":[],"actions":{"create":[],"call":["NoOp"]}},{"name":"opt_in","args":[],"returns":{"type":"void"},"events":[],"actions":{"create":[],"call":["OptIn"]}},{"name":"emitSwapped","args":[{"name":"a","type":"uint64"},{"name":"b","type":"uint64"}],"returns":{"type":"void"},"events":[],"actions":{"create":[],"call":["NoOp"]}},{"name":"emitSwappedTwice","args":[{"name":"a","type":"uint64"},{"name":"b","type":"uint64"}],"returns":{"type":"void"},"events":[],"actions":{"create":[],"call":["NoOp"]}},{"name":"emitComplex","args":[{"name":"a","type":"uint64"},{"name":"b","type":"uint64"},{"name":"array","type":"uint32[]"}],"returns":{"type":"void"},"events":[],"actions":{"create":[],"call":["NoOp"]}}],"state":{"schema":{"global":{"ints":3,"bytes":2},"local":{"ints":2,"bytes":2}},"keys":{"global":{"bytes1":{"key":"Ynl0ZXMx","keyType":"AVMString","valueType":"AVMBytes","desc":""},"bytes2":{"key":"Ynl0ZXMy","keyType":"AVMString","valueType":"AVMBytes","desc":""},"int1":{"key":"aW50MQ==","keyType":"AVMString","valueType":"AVMUint64","desc":""},"int2":{"key":"aW50Mg==","keyType":"AVMString","valueType":"AVMUint64","desc":""},"value":{"key":"dmFsdWU=","keyType":"AVMString","valueType":"AVMUint64","desc":""}},"local":{"local_bytes1":{"key":"bG9jYWxfYnl0ZXMx","keyType":"AVMString","valueType":"AVMBytes","desc":""},"local_bytes2":{"key":"bG9jYWxfYnl0ZXMy","keyType":"AVMString","valueType":"AVMBytes","desc":""},"local_int1":{"key":"bG9jYWxfaW50MQ==","keyType":"AVMString","valueType":"AVMUint64","desc":""},"local_int2":{"key":"bG9jYWxfaW50Mg==","keyType":"AVMString","valueType":"AVMUint64","desc":""}},"box":{}},"maps":{"global":{},"local":{},"box":{}}},"source":{"approval":"I3ByYWdtYSB2ZXJzaW9uIDgKaW50Y2Jsb2NrIDAgMSAxMApieXRlY2Jsb2NrIDB4IDB4MWNjYmQ5MjUgMHgxNTFmN2M3NQp0eG4gTnVtQXBwQXJncwppbnRjXzAgLy8gMAo9PQpibnogbWFpbl9sMjQKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMApwdXNoYnl0ZXMgMHhmMTdlODBhNSAvLyAiY2FsbF9hYmkoc3RyaW5nKXN0cmluZyIKPT0KYm56IG1haW5fbDIzCnR4bmEgQXBwbGljYXRpb25BcmdzIDAKcHVzaGJ5dGVzIDB4YWQ3NTYwMmMgLy8gImNhbGxfYWJpX2ZvcmVpZ25fcmVmcygpc3RyaW5nIgo9PQpibnogbWFpbl9sMjIKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMApwdXNoYnl0ZXMgMHhhNGNmOGRlYSAvLyAic2V0X2dsb2JhbCh1aW50NjQsdWludDY0LHN0cmluZyxieXRlWzRdKXZvaWQiCj09CmJueiBtYWluX2wyMQp0eG5hIEFwcGxpY2F0aW9uQXJncyAwCnB1c2hieXRlcyAweGNlYzI4MzRhIC8vICJzZXRfbG9jYWwodWludDY0LHVpbnQ2NCxzdHJpbmcsYnl0ZVs0XSl2b2lkIgo9PQpibnogbWFpbl9sMjAKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMApwdXNoYnl0ZXMgMHg5OGJlMjIxOSAvLyAiaXNzdWVfdHJhbnNmZXJfdG9fc2VuZGVyKHVpbnQ2NCl2b2lkIgo9PQpibnogbWFpbl9sMTkKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMApwdXNoYnl0ZXMgMHhhNGI0YTIzMCAvLyAic2V0X2JveChieXRlWzRdLHN0cmluZyl2b2lkIgo9PQpibnogbWFpbl9sMTgKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMApwdXNoYnl0ZXMgMHg0NGQwZGEwZCAvLyAiZXJyb3IoKXZvaWQiCj09CmJueiBtYWluX2wxNwp0eG5hIEFwcGxpY2F0aW9uQXJncyAwCnB1c2hieXRlcyAweDMwYzZkNThhIC8vICJvcHRfaW4oKXZvaWQiCj09CmJueiBtYWluX2wxNgp0eG5hIEFwcGxpY2F0aW9uQXJncyAwCnB1c2hieXRlcyAweGQ0M2NlZTVkIC8vICJlbWl0U3dhcHBlZCh1aW50NjQsdWludDY0KXZvaWQiCj09CmJueiBtYWluX2wxNQp0eG5hIEFwcGxpY2F0aW9uQXJncyAwCnB1c2hieXRlcyAweDExYjA5NzVhIC8vICJlbWl0U3dhcHBlZFR3aWNlKHVpbnQ2NCx1aW50NjQpdm9pZCIKPT0KYm56IG1haW5fbDE0CnR4bmEgQXBwbGljYXRpb25BcmdzIDAKcHVzaGJ5dGVzIDB4YWQyMzBkMGMgLy8gImVtaXRDb21wbGV4KHVpbnQ2NCx1aW50NjQsdWludDMyW10pdm9pZCIKPT0KYm56IG1haW5fbDEzCmVycgptYWluX2wxMzoKdHhuIE9uQ29tcGxldGlvbgppbnRjXzAgLy8gTm9PcAo9PQp0eG4gQXBwbGljYXRpb25JRAppbnRjXzAgLy8gMAohPQomJgphc3NlcnQKY2FsbHN1YiBlbWl0Q29tcGxleGNhc3Rlcl8yNQppbnRjXzEgLy8gMQpyZXR1cm4KbWFpbl9sMTQ6CnR4biBPbkNvbXBsZXRpb24KaW50Y18wIC8vIE5vT3AKPT0KdHhuIEFwcGxpY2F0aW9uSUQKaW50Y18wIC8vIDAKIT0KJiYKYXNzZXJ0CmNhbGxzdWIgZW1pdFN3YXBwZWRUd2ljZWNhc3Rlcl8yNAppbnRjXzEgLy8gMQpyZXR1cm4KbWFpbl9sMTU6CnR4biBPbkNvbXBsZXRpb24KaW50Y18wIC8vIE5vT3AKPT0KdHhuIEFwcGxpY2F0aW9uSUQKaW50Y18wIC8vIDAKIT0KJiYKYXNzZXJ0CmNhbGxzdWIgZW1pdFN3YXBwZWRjYXN0ZXJfMjMKaW50Y18xIC8vIDEKcmV0dXJuCm1haW5fbDE2Ogp0eG4gT25Db21wbGV0aW9uCmludGNfMSAvLyBPcHRJbgo9PQp0eG4gQXBwbGljYXRpb25JRAppbnRjXzAgLy8gMAohPQomJgphc3NlcnQKY2FsbHN1YiBvcHRpbmNhc3Rlcl8yMgppbnRjXzEgLy8gMQpyZXR1cm4KbWFpbl9sMTc6CnR4biBPbkNvbXBsZXRpb24KaW50Y18wIC8vIE5vT3AKPT0KdHhuIEFwcGxpY2F0aW9uSUQKaW50Y18wIC8vIDAKIT0KJiYKYXNzZXJ0CmNhbGxzdWIgZXJyb3JjYXN0ZXJfMjEKaW50Y18xIC8vIDEKcmV0dXJuCm1haW5fbDE4Ogp0eG4gT25Db21wbGV0aW9uCmludGNfMCAvLyBOb09wCj09CnR4biBBcHBsaWNhdGlvbklECmludGNfMCAvLyAwCiE9CiYmCmFzc2VydApjYWxsc3ViIHNldGJveGNhc3Rlcl8yMAppbnRjXzEgLy8gMQpyZXR1cm4KbWFpbl9sMTk6CnR4biBPbkNvbXBsZXRpb24KaW50Y18wIC8vIE5vT3AKPT0KdHhuIEFwcGxpY2F0aW9uSUQKaW50Y18wIC8vIDAKIT0KJiYKYXNzZXJ0CmNhbGxzdWIgaXNzdWV0cmFuc2ZlcnRvc2VuZGVyY2FzdGVyXzE5CmludGNfMSAvLyAxCnJldHVybgptYWluX2wyMDoKdHhuIE9uQ29tcGxldGlvbgppbnRjXzAgLy8gTm9PcAo9PQp0eG4gQXBwbGljYXRpb25JRAppbnRjXzAgLy8gMAohPQomJgphc3NlcnQKY2FsbHN1YiBzZXRsb2NhbGNhc3Rlcl8xOAppbnRjXzEgLy8gMQpyZXR1cm4KbWFpbl9sMjE6CnR4biBPbkNvbXBsZXRpb24KaW50Y18wIC8vIE5vT3AKPT0KdHhuIEFwcGxpY2F0aW9uSUQKaW50Y18wIC8vIDAKIT0KJiYKYXNzZXJ0CmNhbGxzdWIgc2V0Z2xvYmFsY2FzdGVyXzE3CmludGNfMSAvLyAxCnJldHVybgptYWluX2wyMjoKdHhuIE9uQ29tcGxldGlvbgppbnRjXzAgLy8gTm9PcAo9PQp0eG4gQXBwbGljYXRpb25JRAppbnRjXzAgLy8gMAohPQomJgphc3NlcnQKY2FsbHN1YiBjYWxsYWJpZm9yZWlnbnJlZnNjYXN0ZXJfMTYKaW50Y18xIC8vIDEKcmV0dXJuCm1haW5fbDIzOgp0eG4gT25Db21wbGV0aW9uCmludGNfMCAvLyBOb09wCj09CnR4biBBcHBsaWNhdGlvbklECmludGNfMCAvLyAwCiE9CiYmCmFzc2VydApjYWxsc3ViIGNhbGxhYmljYXN0ZXJfMTUKaW50Y18xIC8vIDEKcmV0dXJuCm1haW5fbDI0Ogp0eG4gT25Db21wbGV0aW9uCmludGNfMCAvLyBOb09wCj09CmJueiBtYWluX2wzMgp0eG4gT25Db21wbGV0aW9uCmludGNfMSAvLyBPcHRJbgo9PQpibnogbWFpbl9sMzEKdHhuIE9uQ29tcGxldGlvbgpwdXNoaW50IDQgLy8gVXBkYXRlQXBwbGljYXRpb24KPT0KYm56IG1haW5fbDMwCnR4biBPbkNvbXBsZXRpb24KcHVzaGludCA1IC8vIERlbGV0ZUFwcGxpY2F0aW9uCj09CmJueiBtYWluX2wyOQplcnIKbWFpbl9sMjk6CnR4biBBcHBsaWNhdGlvbklECmludGNfMCAvLyAwCiE9CmFzc2VydApjYWxsc3ViIGRlbGV0ZV8xMAppbnRjXzEgLy8gMQpyZXR1cm4KbWFpbl9sMzA6CnR4biBBcHBsaWNhdGlvbklECmludGNfMCAvLyAwCiE9CmFzc2VydApjYWxsc3ViIHVwZGF0ZV85CmludGNfMSAvLyAxCnJldHVybgptYWluX2wzMToKdHhuIEFwcGxpY2F0aW9uSUQKaW50Y18wIC8vIDAKPT0KYXNzZXJ0CmNhbGxzdWIgY3JlYXRlXzgKaW50Y18xIC8vIDEKcmV0dXJuCm1haW5fbDMyOgp0eG4gQXBwbGljYXRpb25JRAppbnRjXzAgLy8gMAo9PQphc3NlcnQKY2FsbHN1YiBjcmVhdGVfOAppbnRjXzEgLy8gMQpyZXR1cm4KCi8vIGNhbGxfYWJpCmNhbGxhYmlfMDoKcHJvdG8gMSAxCmJ5dGVjXzAgLy8gIiIKcHVzaGJ5dGVzIDB4NDg2NTZjNmM2ZjJjMjAgLy8gIkhlbGxvLCAiCmZyYW1lX2RpZyAtMQpleHRyYWN0IDIgMApjb25jYXQKZnJhbWVfYnVyeSAwCmZyYW1lX2RpZyAwCmxlbgppdG9iCmV4dHJhY3QgNiAwCmZyYW1lX2RpZyAwCmNvbmNhdApmcmFtZV9idXJ5IDAKcmV0c3ViCgovLyBpdG9hCml0b2FfMToKcHJvdG8gMSAxCmZyYW1lX2RpZyAtMQppbnRjXzAgLy8gMAo9PQpibnogaXRvYV8xX2w1CmZyYW1lX2RpZyAtMQppbnRjXzIgLy8gMTAKLwppbnRjXzAgLy8gMAo+CmJueiBpdG9hXzFfbDQKYnl0ZWNfMCAvLyAiIgppdG9hXzFfbDM6CnB1c2hieXRlcyAweDMwMzEzMjMzMzQzNTM2MzczODM5IC8vICIwMTIzNDU2Nzg5IgpmcmFtZV9kaWcgLTEKaW50Y18yIC8vIDEwCiUKaW50Y18xIC8vIDEKZXh0cmFjdDMKY29uY2F0CmIgaXRvYV8xX2w2Cml0b2FfMV9sNDoKZnJhbWVfZGlnIC0xCmludGNfMiAvLyAxMAovCmNhbGxzdWIgaXRvYV8xCmIgaXRvYV8xX2wzCml0b2FfMV9sNToKcHVzaGJ5dGVzIDB4MzAgLy8gIjAiCml0b2FfMV9sNjoKcmV0c3ViCgovLyBjYWxsX2FiaV9mb3JlaWduX3JlZnMKY2FsbGFiaWZvcmVpZ25yZWZzXzI6CnByb3RvIDAgMQpieXRlY18wIC8vICIiCnB1c2hieXRlcyAweDQxNzA3MDNhMjAgLy8gIkFwcDogIgp0eG5hIEFwcGxpY2F0aW9ucyAxCmNhbGxzdWIgaXRvYV8xCmNvbmNhdApwdXNoYnl0ZXMgMHgyYzIwNDE3MzczNjU3NDNhMjAgLy8gIiwgQXNzZXQ6ICIKY29uY2F0CnR4bmEgQXNzZXRzIDAKY2FsbHN1YiBpdG9hXzEKY29uY2F0CnB1c2hieXRlcyAweDJjMjA0MTYzNjM2Zjc1NmU3NDNhMjAgLy8gIiwgQWNjb3VudDogIgpjb25jYXQKdHhuYSBBY2NvdW50cyAwCmludGNfMCAvLyAwCmdldGJ5dGUKY2FsbHN1YiBpdG9hXzEKY29uY2F0CnB1c2hieXRlcyAweDNhIC8vICI6Igpjb25jYXQKdHhuYSBBY2NvdW50cyAwCmludGNfMSAvLyAxCmdldGJ5dGUKY2FsbHN1YiBpdG9hXzEKY29uY2F0CmZyYW1lX2J1cnkgMApmcmFtZV9kaWcgMApsZW4KaXRvYgpleHRyYWN0IDYgMApmcmFtZV9kaWcgMApjb25jYXQKZnJhbWVfYnVyeSAwCnJldHN1YgoKLy8gc2V0X2dsb2JhbApzZXRnbG9iYWxfMzoKcHJvdG8gNCAwCnB1c2hieXRlcyAweDY5NmU3NDMxIC8vICJpbnQxIgpmcmFtZV9kaWcgLTQKYXBwX2dsb2JhbF9wdXQKcHVzaGJ5dGVzIDB4Njk2ZTc0MzIgLy8gImludDIiCmZyYW1lX2RpZyAtMwphcHBfZ2xvYmFsX3B1dApwdXNoYnl0ZXMgMHg2Mjc5NzQ2NTczMzEgLy8gImJ5dGVzMSIKZnJhbWVfZGlnIC0yCmV4dHJhY3QgMiAwCmFwcF9nbG9iYWxfcHV0CnB1c2hieXRlcyAweDYyNzk3NDY1NzMzMiAvLyAiYnl0ZXMyIgpmcmFtZV9kaWcgLTEKYXBwX2dsb2JhbF9wdXQKcmV0c3ViCgovLyBzZXRfbG9jYWwKc2V0bG9jYWxfNDoKcHJvdG8gNCAwCnR4biBTZW5kZXIKcHVzaGJ5dGVzIDB4NmM2ZjYzNjE2YzVmNjk2ZTc0MzEgLy8gImxvY2FsX2ludDEiCmZyYW1lX2RpZyAtNAphcHBfbG9jYWxfcHV0CnR4biBTZW5kZXIKcHVzaGJ5dGVzIDB4NmM2ZjYzNjE2YzVmNjk2ZTc0MzIgLy8gImxvY2FsX2ludDIiCmZyYW1lX2RpZyAtMwphcHBfbG9jYWxfcHV0CnR4biBTZW5kZXIKcHVzaGJ5dGVzIDB4NmM2ZjYzNjE2YzVmNjI3OTc0NjU3MzMxIC8vICJsb2NhbF9ieXRlczEiCmZyYW1lX2RpZyAtMgpleHRyYWN0IDIgMAphcHBfbG9jYWxfcHV0CnR4biBTZW5kZXIKcHVzaGJ5dGVzIDB4NmM2ZjYzNjE2YzVmNjI3OTc0NjU3MzMyIC8vICJsb2NhbF9ieXRlczIiCmZyYW1lX2RpZyAtMQphcHBfbG9jYWxfcHV0CnJldHN1YgoKLy8gaXNzdWVfdHJhbnNmZXJfdG9fc2VuZGVyCmlzc3VldHJhbnNmZXJ0b3NlbmRlcl81Ogpwcm90byAxIDAKaXR4bl9iZWdpbgppbnRjXzEgLy8gcGF5Cml0eG5fZmllbGQgVHlwZUVudW0KZnJhbWVfZGlnIC0xCml0eG5fZmllbGQgQW1vdW50CnR4biBTZW5kZXIKaXR4bl9maWVsZCBSZWNlaXZlcgppbnRjXzAgLy8gMAppdHhuX2ZpZWxkIEZlZQppdHhuX3N1Ym1pdApyZXRzdWIKCi8vIHNldF9ib3gKc2V0Ym94XzY6CnByb3RvIDIgMApmcmFtZV9kaWcgLTIKYm94X2RlbApwb3AKZnJhbWVfZGlnIC0yCmZyYW1lX2RpZyAtMQpleHRyYWN0IDIgMApib3hfcHV0CnJldHN1YgoKLy8gZXJyb3IKZXJyb3JfNzoKcHJvdG8gMCAwCmludGNfMCAvLyAwCi8vIERlbGliZXJhdGUgZXJyb3IKYXNzZXJ0CnJldHN1YgoKLy8gY3JlYXRlCmNyZWF0ZV84Ogpwcm90byAwIDAKaW50Y18xIC8vIDEKcmV0dXJuCgovLyB1cGRhdGUKdXBkYXRlXzk6CnByb3RvIDAgMAp0eG4gU2VuZGVyCmdsb2JhbCBDcmVhdG9yQWRkcmVzcwo9PQovLyB1bmF1dGhvcml6ZWQKYXNzZXJ0CmludGNfMSAvLyAxCnJldHVybgoKLy8gZGVsZXRlCmRlbGV0ZV8xMDoKcHJvdG8gMCAwCnR4biBTZW5kZXIKZ2xvYmFsIENyZWF0b3JBZGRyZXNzCj09Ci8vIHVuYXV0aG9yaXplZAphc3NlcnQKaW50Y18xIC8vIDEKcmV0dXJuCgovLyBvcHRfaW4Kb3B0aW5fMTE6CnByb3RvIDAgMAppbnRjXzEgLy8gMQpyZXR1cm4KCi8vIGVtaXRTd2FwcGVkCmVtaXRTd2FwcGVkXzEyOgpwcm90byAyIDAKYnl0ZWNfMSAvLyAiU3dhcHBlZCh1aW50NjQsdWludDY0KSIKZnJhbWVfZGlnIC0yCml0b2IKY29uY2F0CmZyYW1lX2RpZyAtMQppdG9iCmNvbmNhdApsb2cKaW50Y18xIC8vIDEKcmV0dXJuCgovLyBlbWl0U3dhcHBlZFR3aWNlCmVtaXRTd2FwcGVkVHdpY2VfMTM6CnByb3RvIDIgMApieXRlY18xIC8vICJTd2FwcGVkKHVpbnQ2NCx1aW50NjQpIgpmcmFtZV9kaWcgLTIKaXRvYgpjb25jYXQKZnJhbWVfZGlnIC0xCml0b2IKY29uY2F0CmxvZwpieXRlY18xIC8vICJTd2FwcGVkKHVpbnQ2NCx1aW50NjQpIgpmcmFtZV9kaWcgLTEKaXRvYgpjb25jYXQKZnJhbWVfZGlnIC0yCml0b2IKY29uY2F0CmxvZwppbnRjXzEgLy8gMQpyZXR1cm4KCi8vIGVtaXRDb21wbGV4CmVtaXRDb21wbGV4XzE0Ogpwcm90byAzIDAKYnl0ZWNfMCAvLyAiIgppbnRjXzAgLy8gMApkdXAKYnl0ZWNfMCAvLyAiIgpkdXAKYnl0ZWNfMSAvLyAiU3dhcHBlZCh1aW50NjQsdWludDY0KSIKZnJhbWVfZGlnIC0zCml0b2IKY29uY2F0CmZyYW1lX2RpZyAtMgppdG9iCmNvbmNhdApsb2cKZnJhbWVfZGlnIC0xCmZyYW1lX2J1cnkgNApmcmFtZV9kaWcgNApmcmFtZV9idXJ5IDMKaW50Y18yIC8vIDEwCmZyYW1lX2J1cnkgMQpmcmFtZV9kaWcgMQppdG9iCmV4dHJhY3QgNiAwCmZyYW1lX2RpZyAtMgppdG9iCmNvbmNhdApmcmFtZV9kaWcgMwpjb25jYXQKZnJhbWVfYnVyeSAwCnB1c2hieXRlcyAweDE4ZGE1ZWE3IC8vICJDb21wbGV4KHVpbnQzMltdLHVpbnQ2NCkiCmZyYW1lX2RpZyAwCmNvbmNhdApsb2cKaW50Y18xIC8vIDEKcmV0dXJuCgovLyBjYWxsX2FiaV9jYXN0ZXIKY2FsbGFiaWNhc3Rlcl8xNToKcHJvdG8gMCAwCmJ5dGVjXzAgLy8gIiIKZHVwCnR4bmEgQXBwbGljYXRpb25BcmdzIDEKZnJhbWVfYnVyeSAxCmZyYW1lX2RpZyAxCmNhbGxzdWIgY2FsbGFiaV8wCmZyYW1lX2J1cnkgMApieXRlY18yIC8vIDB4MTUxZjdjNzUKZnJhbWVfZGlnIDAKY29uY2F0CmxvZwpyZXRzdWIKCi8vIGNhbGxfYWJpX2ZvcmVpZ25fcmVmc19jYXN0ZXIKY2FsbGFiaWZvcmVpZ25yZWZzY2FzdGVyXzE2Ogpwcm90byAwIDAKYnl0ZWNfMCAvLyAiIgpjYWxsc3ViIGNhbGxhYmlmb3JlaWducmVmc18yCmZyYW1lX2J1cnkgMApieXRlY18yIC8vIDB4MTUxZjdjNzUKZnJhbWVfZGlnIDAKY29uY2F0CmxvZwpyZXRzdWIKCi8vIHNldF9nbG9iYWxfY2FzdGVyCnNldGdsb2JhbGNhc3Rlcl8xNzoKcHJvdG8gMCAwCmludGNfMCAvLyAwCmR1cApieXRlY18wIC8vICIiCmR1cAp0eG5hIEFwcGxpY2F0aW9uQXJncyAxCmJ0b2kKZnJhbWVfYnVyeSAwCnR4bmEgQXBwbGljYXRpb25BcmdzIDIKYnRvaQpmcmFtZV9idXJ5IDEKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwpmcmFtZV9idXJ5IDIKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNApmcmFtZV9idXJ5IDMKZnJhbWVfZGlnIDAKZnJhbWVfZGlnIDEKZnJhbWVfZGlnIDIKZnJhbWVfZGlnIDMKY2FsbHN1YiBzZXRnbG9iYWxfMwpyZXRzdWIKCi8vIHNldF9sb2NhbF9jYXN0ZXIKc2V0bG9jYWxjYXN0ZXJfMTg6CnByb3RvIDAgMAppbnRjXzAgLy8gMApkdXAKYnl0ZWNfMCAvLyAiIgpkdXAKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQpidG9pCmZyYW1lX2J1cnkgMAp0eG5hIEFwcGxpY2F0aW9uQXJncyAyCmJ0b2kKZnJhbWVfYnVyeSAxCnR4bmEgQXBwbGljYXRpb25BcmdzIDMKZnJhbWVfYnVyeSAyCnR4bmEgQXBwbGljYXRpb25BcmdzIDQKZnJhbWVfYnVyeSAzCmZyYW1lX2RpZyAwCmZyYW1lX2RpZyAxCmZyYW1lX2RpZyAyCmZyYW1lX2RpZyAzCmNhbGxzdWIgc2V0bG9jYWxfNApyZXRzdWIKCi8vIGlzc3VlX3RyYW5zZmVyX3RvX3NlbmRlcl9jYXN0ZXIKaXNzdWV0cmFuc2ZlcnRvc2VuZGVyY2FzdGVyXzE5Ogpwcm90byAwIDAKaW50Y18wIC8vIDAKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQpidG9pCmZyYW1lX2J1cnkgMApmcmFtZV9kaWcgMApjYWxsc3ViIGlzc3VldHJhbnNmZXJ0b3NlbmRlcl81CnJldHN1YgoKLy8gc2V0X2JveF9jYXN0ZXIKc2V0Ym94Y2FzdGVyXzIwOgpwcm90byAwIDAKYnl0ZWNfMCAvLyAiIgpkdXAKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQpmcmFtZV9idXJ5IDAKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgpmcmFtZV9idXJ5IDEKZnJhbWVfZGlnIDAKZnJhbWVfZGlnIDEKY2FsbHN1YiBzZXRib3hfNgpyZXRzdWIKCi8vIGVycm9yX2Nhc3RlcgplcnJvcmNhc3Rlcl8yMToKcHJvdG8gMCAwCmNhbGxzdWIgZXJyb3JfNwpyZXRzdWIKCi8vIG9wdF9pbl9jYXN0ZXIKb3B0aW5jYXN0ZXJfMjI6CnByb3RvIDAgMApjYWxsc3ViIG9wdGluXzExCnJldHN1YgoKLy8gZW1pdFN3YXBwZWRfY2FzdGVyCmVtaXRTd2FwcGVkY2FzdGVyXzIzOgpwcm90byAwIDAKaW50Y18wIC8vIDAKZHVwCnR4bmEgQXBwbGljYXRpb25BcmdzIDEKYnRvaQpmcmFtZV9idXJ5IDAKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgpidG9pCmZyYW1lX2J1cnkgMQpmcmFtZV9kaWcgMApmcmFtZV9kaWcgMQpjYWxsc3ViIGVtaXRTd2FwcGVkXzEyCnJldHN1YgoKLy8gZW1pdFN3YXBwZWRUd2ljZV9jYXN0ZXIKZW1pdFN3YXBwZWRUd2ljZWNhc3Rlcl8yNDoKcHJvdG8gMCAwCmludGNfMCAvLyAwCmR1cAp0eG5hIEFwcGxpY2F0aW9uQXJncyAxCmJ0b2kKZnJhbWVfYnVyeSAwCnR4bmEgQXBwbGljYXRpb25BcmdzIDIKYnRvaQpmcmFtZV9idXJ5IDEKZnJhbWVfZGlnIDAKZnJhbWVfZGlnIDEKY2FsbHN1YiBlbWl0U3dhcHBlZFR3aWNlXzEzCnJldHN1YgoKLy8gZW1pdENvbXBsZXhfY2FzdGVyCmVtaXRDb21wbGV4Y2FzdGVyXzI1Ogpwcm90byAwIDAKaW50Y18wIC8vIDAKZHVwCmJ5dGVjXzAgLy8gIiIKdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQpidG9pCmZyYW1lX2J1cnkgMAp0eG5hIEFwcGxpY2F0aW9uQXJncyAyCmJ0b2kKZnJhbWVfYnVyeSAxCnR4bmEgQXBwbGljYXRpb25BcmdzIDMKZnJhbWVfYnVyeSAyCmZyYW1lX2RpZyAwCmZyYW1lX2RpZyAxCmZyYW1lX2RpZyAyCmNhbGxzdWIgZW1pdENvbXBsZXhfMTQKcmV0c3Vi","clear":"I3ByYWdtYSB2ZXJzaW9uIDgKcHVzaGludCAwIC8vIDAKcmV0dXJu"},"bareActions":{"create":["NoOp","OptIn"],"call":["DeleteApplication","UpdateApplication"]}} as unknown as Arc56Contract /** - * Defines an onCompletionAction of 'no_op' - */ -export type OnCompleteNoOp = { onCompleteAction?: 'no_op' | OnApplicationComplete.NoOpOC } -/** - * Defines an onCompletionAction of 'opt_in' - */ -export type OnCompleteOptIn = { onCompleteAction: 'opt_in' | OnApplicationComplete.OptInOC } -/** - * Defines an onCompletionAction of 'close_out' - */ -export type OnCompleteCloseOut = { onCompleteAction: 'close_out' | OnApplicationComplete.CloseOutOC } -/** - * Defines an onCompletionAction of 'delete_application' - */ -export type OnCompleteDelApp = { onCompleteAction: 'delete_application' | OnApplicationComplete.DeleteApplicationOC } -/** - * Defines an onCompletionAction of 'update_application' - */ -export type OnCompleteUpdApp = { onCompleteAction: 'update_application' | OnApplicationComplete.UpdateApplicationOC } -/** - * A state record containing a single unsigned integer + * A state record containing binary data */ -export type IntegerState = { +export interface BinaryState { /** - * Gets the state value as a BigInt + * Gets the state value as a Uint8Array */ - asBigInt(): bigint + asByteArray(): Uint8Array | undefined /** - * Gets the state value as a number. + * Gets the state value as a string */ - asNumber(): number + asString(): string | undefined +} + +class BinaryStateValue implements BinaryState { + constructor(private value: Uint8Array | undefined) {} + + asByteArray(): Uint8Array | undefined { + return this.value + } + + asString(): string | undefined { + return this.value !== undefined ? Buffer.from(this.value).toString('utf-8') : undefined + } } + /** - * A state record containing binary data + * Expands types for IntelliSense so they are more human readable + * See https://stackoverflow.com/a/69288824 + */ +export type Expand = T extends (...args: infer A) => infer R + ? (...args: Expand) => Expand + : T extends infer O + ? { [K in keyof O]: O[K] } + : never + + +/** + * The argument types for the TestingApp contract */ -export type BinaryState = { +export type TestingAppArgs = { /** - * Gets the state value as a Uint8Array + * The object representation of the arguments for each method */ - asByteArray(): Uint8Array + obj: { + 'call_abi(string)string': { + value: string + } + 'call_abi_foreign_refs()string': Record + 'set_global(uint64,uint64,string,byte[4])void': { + int1: bigint | number + int2: bigint | number + bytes1: string + bytes2: Uint8Array + } + 'set_local(uint64,uint64,string,byte[4])void': { + int1: bigint | number + int2: bigint | number + bytes1: string + bytes2: Uint8Array + } + 'issue_transfer_to_sender(uint64)void': { + amount: bigint | number + } + 'set_box(byte[4],string)void': { + name: Uint8Array + value: string + } + 'error()void': Record + 'opt_in()void': Record + 'emitSwapped(uint64,uint64)void': { + a: bigint | number + b: bigint | number + } + 'emitSwappedTwice(uint64,uint64)void': { + a: bigint | number + b: bigint | number + } + 'emitComplex(uint64,uint64,uint32[])void': { + a: bigint | number + b: bigint | number + array: bigint | number[] + } + } /** - * Gets the state value as a string - */ - asString(): string + * The tuple representation of the arguments for each method + */ + tuple: { + 'call_abi(string)string': [value: string] + 'call_abi_foreign_refs()string': [] + 'set_global(uint64,uint64,string,byte[4])void': [int1: bigint | number, int2: bigint | number, bytes1: string, bytes2: Uint8Array] + 'set_local(uint64,uint64,string,byte[4])void': [int1: bigint | number, int2: bigint | number, bytes1: string, bytes2: Uint8Array] + 'issue_transfer_to_sender(uint64)void': [amount: bigint | number] + 'set_box(byte[4],string)void': [name: Uint8Array, value: string] + 'error()void': [] + 'opt_in()void': [] + 'emitSwapped(uint64,uint64)void': [a: bigint | number, b: bigint | number] + 'emitSwappedTwice(uint64,uint64)void': [a: bigint | number, b: bigint | number] + 'emitComplex(uint64,uint64,uint32[])void': [a: bigint | number, b: bigint | number, array: bigint | number[]] + } } -export type AppCreateCallTransactionResult = AppCallTransactionResult & Partial & AppReference -export type AppUpdateCallTransactionResult = AppCallTransactionResult & Partial +/** + * The return type for each method + */ +export type TestingAppReturns = { + 'call_abi(string)string': string + 'call_abi_foreign_refs()string': string + 'set_global(uint64,uint64,string,byte[4])void': void + 'set_local(uint64,uint64,string,byte[4])void': void + 'issue_transfer_to_sender(uint64)void': void + 'set_box(byte[4],string)void': void + 'error()void': void + 'opt_in()void': void + 'emitSwapped(uint64,uint64)void': void + 'emitSwappedTwice(uint64,uint64)void': void + 'emitComplex(uint64,uint64,uint32[])void': void +} /** * Defines the types of available calls and state of the TestingApp smart contract. */ -export type TestingApp = { +export type TestingAppTypes = { /** * Maps method signatures / names to their argument and return types. */ - methods: Record< - 'call_abi(string)string' | 'call_abi', - { - argsObj: { - value: string - } - argsTuple: [value: string] - returns: string - } - > & - Record< - 'call_abi_foreign_refs()string' | 'call_abi_foreign_refs', - { - argsObj: {} - argsTuple: [] - returns: string - } - > & - Record< - 'set_global(uint64,uint64,string,byte[4])void' | 'set_global', - { - argsObj: { - int1: bigint | number - int2: bigint | number - bytes1: string - bytes2: Uint8Array - } - argsTuple: [int1: bigint | number, int2: bigint | number, bytes1: string, bytes2: Uint8Array] - returns: void - } - > & - Record< - 'set_local(uint64,uint64,string,byte[4])void' | 'set_local', - { - argsObj: { - int1: bigint | number - int2: bigint | number - bytes1: string - bytes2: Uint8Array - } - argsTuple: [int1: bigint | number, int2: bigint | number, bytes1: string, bytes2: Uint8Array] - returns: void - } - > & - Record< - 'issue_transfer_to_sender(uint64)void' | 'issue_transfer_to_sender', - { - argsObj: { - amount: bigint | number - } - argsTuple: [amount: bigint | number] - returns: void - } - > & - Record< - 'set_box(byte[4],string)void' | 'set_box', - { - argsObj: { - name: Uint8Array - value: string - } - argsTuple: [name: Uint8Array, value: string] - returns: void - } - > & - Record< - 'error()void' | 'error', - { - argsObj: {} - argsTuple: [] - returns: void - } - > & - Record< - 'opt_in()void' | 'opt_in', - { - argsObj: {} - argsTuple: [] - returns: void - } - > & - Record< - 'emitSwapped(uint64,uint64)void' | 'emitSwapped', - { - argsObj: { - a: bigint | number - b: bigint | number - } - argsTuple: [a: bigint | number, b: bigint | number] - returns: void - } - > & - Record< - 'emitSwappedTwice(uint64,uint64)void' | 'emitSwappedTwice', - { - argsObj: { - a: bigint | number - b: bigint | number - } - argsTuple: [a: bigint | number, b: bigint | number] - returns: void - } - > & - Record< - 'emitComplex(uint64,uint64,uint32[])void' | 'emitComplex', - { - argsObj: { - a: bigint | number - b: bigint | number - array: number[] - } - argsTuple: [a: bigint | number, b: bigint | number, array: number[]] - returns: void - } - > - /** - * Defines the shape of the global and local state of the application. + methods: + & Record<'call_abi(string)string' | 'call_abi', { + argsObj: TestingAppArgs['obj']['call_abi(string)string'] + argsTuple: TestingAppArgs['tuple']['call_abi(string)string'] + returns: TestingAppReturns['call_abi(string)string'] + }> + & Record<'call_abi_foreign_refs()string' | 'call_abi_foreign_refs', { + argsObj: TestingAppArgs['obj']['call_abi_foreign_refs()string'] + argsTuple: TestingAppArgs['tuple']['call_abi_foreign_refs()string'] + returns: TestingAppReturns['call_abi_foreign_refs()string'] + }> + & Record<'set_global(uint64,uint64,string,byte[4])void' | 'set_global', { + argsObj: TestingAppArgs['obj']['set_global(uint64,uint64,string,byte[4])void'] + argsTuple: TestingAppArgs['tuple']['set_global(uint64,uint64,string,byte[4])void'] + returns: TestingAppReturns['set_global(uint64,uint64,string,byte[4])void'] + }> + & Record<'set_local(uint64,uint64,string,byte[4])void' | 'set_local', { + argsObj: TestingAppArgs['obj']['set_local(uint64,uint64,string,byte[4])void'] + argsTuple: TestingAppArgs['tuple']['set_local(uint64,uint64,string,byte[4])void'] + returns: TestingAppReturns['set_local(uint64,uint64,string,byte[4])void'] + }> + & Record<'issue_transfer_to_sender(uint64)void' | 'issue_transfer_to_sender', { + argsObj: TestingAppArgs['obj']['issue_transfer_to_sender(uint64)void'] + argsTuple: TestingAppArgs['tuple']['issue_transfer_to_sender(uint64)void'] + returns: TestingAppReturns['issue_transfer_to_sender(uint64)void'] + }> + & Record<'set_box(byte[4],string)void' | 'set_box', { + argsObj: TestingAppArgs['obj']['set_box(byte[4],string)void'] + argsTuple: TestingAppArgs['tuple']['set_box(byte[4],string)void'] + returns: TestingAppReturns['set_box(byte[4],string)void'] + }> + & Record<'error()void' | 'error', { + argsObj: TestingAppArgs['obj']['error()void'] + argsTuple: TestingAppArgs['tuple']['error()void'] + returns: TestingAppReturns['error()void'] + }> + & Record<'opt_in()void' | 'opt_in', { + argsObj: TestingAppArgs['obj']['opt_in()void'] + argsTuple: TestingAppArgs['tuple']['opt_in()void'] + returns: TestingAppReturns['opt_in()void'] + }> + & Record<'emitSwapped(uint64,uint64)void' | 'emitSwapped', { + argsObj: TestingAppArgs['obj']['emitSwapped(uint64,uint64)void'] + argsTuple: TestingAppArgs['tuple']['emitSwapped(uint64,uint64)void'] + returns: TestingAppReturns['emitSwapped(uint64,uint64)void'] + }> + & Record<'emitSwappedTwice(uint64,uint64)void' | 'emitSwappedTwice', { + argsObj: TestingAppArgs['obj']['emitSwappedTwice(uint64,uint64)void'] + argsTuple: TestingAppArgs['tuple']['emitSwappedTwice(uint64,uint64)void'] + returns: TestingAppReturns['emitSwappedTwice(uint64,uint64)void'] + }> + & Record<'emitComplex(uint64,uint64,uint32[])void' | 'emitComplex', { + argsObj: TestingAppArgs['obj']['emitComplex(uint64,uint64,uint32[])void'] + argsTuple: TestingAppArgs['tuple']['emitComplex(uint64,uint64,uint32[])void'] + returns: TestingAppReturns['emitComplex(uint64,uint64,uint32[])void'] + }> + /** + * Defines the shape of the state of the application. */ state: { global: { - bytes1?: BinaryState - bytes2?: BinaryState - int1?: IntegerState - int2?: IntegerState - value?: IntegerState + keys: { + bytes1: BinaryState + bytes2: BinaryState + int1: bigint + int2: bigint + value: bigint + } } local: { - local_bytes1?: BinaryState - local_bytes2?: BinaryState - local_int1?: IntegerState - local_int2?: IntegerState + keys: { + localBytes1: BinaryState + localBytes2: BinaryState + localInt1: bigint + localInt2: bigint + } } } } + /** - * Defines the possible abi call signatures + * Defines the possible abi call signatures. */ -export type TestingAppSig = keyof TestingApp['methods'] +export type TestingAppSignatures = keyof TestingAppTypes['methods'] /** - * Defines an object containing all relevant parameters for a single call to the contract. Where TSignature is undefined, a bare call is made + * Defines the possible abi call signatures for methods that return a non-void value. */ -export type TypedCallParams = { - method: TSignature - methodArgs: TSignature extends undefined ? undefined : Array -} & AppClientCallCoreParams & - CoreAppCallArgs +export type TestingAppNonVoidMethodSignatures = keyof TestingAppTypes['methods'] extends infer T ? T extends keyof TestingAppTypes['methods'] ? MethodReturn extends void ? never : T : never : never /** - * Defines the arguments required for a bare call + * Defines an object containing all relevant parameters for a single call to the contract. */ -export type BareCallArgs = Omit +export type CallParams = Expand< + Omit & + { + /** The args for the ABI method call, either as an ordered array or an object */ + args: Expand + } +> /** - * Maps a method signature from the TestingApp smart contract to the method's arguments in either tuple of struct form + * Maps a method signature from the TestingApp smart contract to the method's arguments in either tuple or struct form */ -export type MethodArgs = TestingApp['methods'][TSignature]['argsObj' | 'argsTuple'] +export type MethodArgs = TestingAppTypes['methods'][TSignature]['argsObj' | 'argsTuple'] /** * Maps a method signature from the TestingApp smart contract to the method's return type */ -export type MethodReturn = TestingApp['methods'][TSignature]['returns'] +export type MethodReturn = TestingAppTypes['methods'][TSignature]['returns'] /** - * A factory for available 'create' calls + * Defines the shape of the keyed global state of the application. */ -export type TestingAppCreateCalls = (typeof TestingAppCallFactory)['create'] -/** - * Defines supported create methods for this smart contract - */ -export type TestingAppCreateCallParams = TypedCallParams & (OnCompleteNoOp | OnCompleteOptIn) +export type GlobalKeysState = TestingAppTypes['state']['global']['keys'] + /** - * A factory for available 'update' calls + * Defines the shape of the keyed local state of the application. */ -export type TestingAppUpdateCalls = (typeof TestingAppCallFactory)['update'] +export type LocalKeysState = TestingAppTypes['state']['local']['keys'] + + /** - * Defines supported update methods for this smart contract + * Defines supported create method params for this smart contract */ -export type TestingAppUpdateCallParams = TypedCallParams +export type TestingAppCreateCallParams = + | Expand /** - * A factory for available 'delete' calls + * Defines supported update method params for this smart contract */ -export type TestingAppDeleteCalls = (typeof TestingAppCallFactory)['delete'] +export type TestingAppUpdateCallParams = + | Expand & {method?: undefined} /** - * Defines supported delete methods for this smart contract + * Defines supported delete method params for this smart contract */ -export type TestingAppDeleteCallParams = TypedCallParams +export type TestingAppDeleteCallParams = + | Expand & {method?: undefined} /** * Defines arguments required for the deploy method. */ -export type TestingAppDeployArgs = { - deployTimeParams?: TealTemplateParams +export type TestingAppDeployParams = Expand & { /** - * A delegate which takes a create call factory and returns the create call params for this smart contract + * Create transaction parameters to use if a create needs to be issued as part of deployment; use `method` to define ABI call (if available) or leave out for a bare call (if available) */ - createCall?: (callFactory: TestingAppCreateCalls) => TestingAppCreateCallParams + createParams?: TestingAppCreateCallParams /** - * A delegate which takes a update call factory and returns the update call params for this smart contract + * Update transaction parameters to use if a create needs to be issued as part of deployment; use `method` to define ABI call (if available) or leave out for a bare call (if available) */ - updateCall?: (callFactory: TestingAppUpdateCalls) => TestingAppUpdateCallParams + updateParams?: TestingAppUpdateCallParams /** - * A delegate which takes a delete call factory and returns the delete call params for this smart contract + * Delete transaction parameters to use if a create needs to be issued as part of deployment; use `method` to define ABI call (if available) or leave out for a bare call (if available) */ - deleteCall?: (callFactory: TestingAppDeleteCalls) => TestingAppDeleteCallParams -} + deleteParams?: TestingAppDeleteCallParams +}> + /** - * Exposes methods for constructing all available smart contract calls + * Exposes methods for constructing `AppClient` params objects for ABI calls to the TestingApp smart contract */ -export abstract class TestingAppCallFactory { - /** - * Gets available create call factories - */ - static get create() { - return { - /** - * Constructs a create call for the TestingApp smart contract using a bare call - * - * @param params Any parameters for the call - * @returns A TypedCallParams object for the call - */ - bare( - params: BareCallArgs & - AppClientCallCoreParams & - CoreAppCallArgs & - AppClientCompilationParams & - (OnCompleteNoOp | OnCompleteOptIn) = {}, - ) { - return { - method: undefined, - methodArgs: undefined, - ...params, - } - }, - } - } - - /** - * Gets available update call factories - */ - static get update() { - return { - /** - * Constructs an update call for the TestingApp smart contract using a bare call - * - * @param params Any parameters for the call - * @returns A TypedCallParams object for the call - */ - bare(params: BareCallArgs & AppClientCallCoreParams & CoreAppCallArgs & AppClientCompilationParams = {}) { - return { - method: undefined, - methodArgs: undefined, - ...params, - } - }, - } - } - - /** - * Gets available delete call factories - */ - static get delete() { - return { - /** - * Constructs a delete call for the TestingApp smart contract using a bare call - * - * @param params Any parameters for the call - * @returns A TypedCallParams object for the call - */ - bare(params: BareCallArgs & AppClientCallCoreParams & CoreAppCallArgs = {}) { - return { - method: undefined, - methodArgs: undefined, - ...params, - } - }, - } - } - +export abstract class TestingAppParamsFactory { /** - * Gets available optIn call factories + * Gets available optIn ABI call param factories */ static get optIn() { return { /** - * Constructs an opt in call for the TestingApp smart contract using the opt_in()void ABI method + * Constructs opt-in ABI call params for the TestingApp smart contract using the opt_in()void ABI method * - * @param args Any args for the contract call - * @param params Any additional parameters for the call - * @returns A TypedCallParams object for the call + * @param params Parameters for the call + * @returns An `AppClientMethodCallParams` object for the call */ - optIn(args: MethodArgs<'opt_in()void'>, params: AppClientCallCoreParams & CoreAppCallArgs = {}) { + optIn(params: CallParams): AppClientMethodCallParams { return { - method: 'opt_in()void' as const, - methodArgs: Array.isArray(args) ? args : [], ...params, + method: 'opt_in()void' as const, + args: Array.isArray(params.args) ? params.args : [], } }, } @@ -691,212 +332,196 @@ export abstract class TestingAppCallFactory { /** * Constructs a no op call for the call_abi(string)string ABI method * - * @param args Any args for the contract call - * @param params Any additional parameters for the call - * @returns A TypedCallParams object for the call + * @param params Parameters for the call + * @returns An `AppClientMethodCallParams` object for the call */ - static callAbi(args: MethodArgs<'call_abi(string)string'>, params: AppClientCallCoreParams & CoreAppCallArgs) { + static callAbi(params: CallParams & CallOnComplete): AppClientMethodCallParams & CallOnComplete { return { - method: 'call_abi(string)string' as const, - methodArgs: Array.isArray(args) ? args : [args.value], ...params, + method: 'call_abi(string)string' as const, + args: Array.isArray(params.args) ? params.args : [params.args.value], } } /** * Constructs a no op call for the call_abi_foreign_refs()string ABI method * - * @param args Any args for the contract call - * @param params Any additional parameters for the call - * @returns A TypedCallParams object for the call + * @param params Parameters for the call + * @returns An `AppClientMethodCallParams` object for the call */ - static callAbiForeignRefs(args: MethodArgs<'call_abi_foreign_refs()string'>, params: AppClientCallCoreParams & CoreAppCallArgs) { + static callAbiForeignRefs(params: CallParams & CallOnComplete): AppClientMethodCallParams & CallOnComplete { return { - method: 'call_abi_foreign_refs()string' as const, - methodArgs: Array.isArray(args) ? args : [], ...params, + method: 'call_abi_foreign_refs()string' as const, + args: Array.isArray(params.args) ? params.args : [], } } /** * Constructs a no op call for the set_global(uint64,uint64,string,byte[4])void ABI method * - * @param args Any args for the contract call - * @param params Any additional parameters for the call - * @returns A TypedCallParams object for the call + * @param params Parameters for the call + * @returns An `AppClientMethodCallParams` object for the call */ - static setGlobal(args: MethodArgs<'set_global(uint64,uint64,string,byte[4])void'>, params: AppClientCallCoreParams & CoreAppCallArgs) { + static setGlobal(params: CallParams & CallOnComplete): AppClientMethodCallParams & CallOnComplete { return { - method: 'set_global(uint64,uint64,string,byte[4])void' as const, - methodArgs: Array.isArray(args) ? args : [args.int1, args.int2, args.bytes1, args.bytes2], ...params, + method: 'set_global(uint64,uint64,string,byte[4])void' as const, + args: Array.isArray(params.args) ? params.args : [params.args.int1, params.args.int2, params.args.bytes1, params.args.bytes2], } } /** * Constructs a no op call for the set_local(uint64,uint64,string,byte[4])void ABI method * - * @param args Any args for the contract call - * @param params Any additional parameters for the call - * @returns A TypedCallParams object for the call + * @param params Parameters for the call + * @returns An `AppClientMethodCallParams` object for the call */ - static setLocal(args: MethodArgs<'set_local(uint64,uint64,string,byte[4])void'>, params: AppClientCallCoreParams & CoreAppCallArgs) { + static setLocal(params: CallParams & CallOnComplete): AppClientMethodCallParams & CallOnComplete { return { - method: 'set_local(uint64,uint64,string,byte[4])void' as const, - methodArgs: Array.isArray(args) ? args : [args.int1, args.int2, args.bytes1, args.bytes2], ...params, + method: 'set_local(uint64,uint64,string,byte[4])void' as const, + args: Array.isArray(params.args) ? params.args : [params.args.int1, params.args.int2, params.args.bytes1, params.args.bytes2], } } /** * Constructs a no op call for the issue_transfer_to_sender(uint64)void ABI method * - * @param args Any args for the contract call - * @param params Any additional parameters for the call - * @returns A TypedCallParams object for the call + * @param params Parameters for the call + * @returns An `AppClientMethodCallParams` object for the call */ - static issueTransferToSender( - args: MethodArgs<'issue_transfer_to_sender(uint64)void'>, - params: AppClientCallCoreParams & CoreAppCallArgs, - ) { + static issueTransferToSender(params: CallParams & CallOnComplete): AppClientMethodCallParams & CallOnComplete { return { - method: 'issue_transfer_to_sender(uint64)void' as const, - methodArgs: Array.isArray(args) ? args : [args.amount], ...params, + method: 'issue_transfer_to_sender(uint64)void' as const, + args: Array.isArray(params.args) ? params.args : [params.args.amount], } } /** * Constructs a no op call for the set_box(byte[4],string)void ABI method * - * @param args Any args for the contract call - * @param params Any additional parameters for the call - * @returns A TypedCallParams object for the call + * @param params Parameters for the call + * @returns An `AppClientMethodCallParams` object for the call */ - static setBox(args: MethodArgs<'set_box(byte[4],string)void'>, params: AppClientCallCoreParams & CoreAppCallArgs) { + static setBox(params: CallParams & CallOnComplete): AppClientMethodCallParams & CallOnComplete { return { - method: 'set_box(byte[4],string)void' as const, - methodArgs: Array.isArray(args) ? args : [args.name, args.value], ...params, + method: 'set_box(byte[4],string)void' as const, + args: Array.isArray(params.args) ? params.args : [params.args.name, params.args.value], } } /** * Constructs a no op call for the error()void ABI method * - * @param args Any args for the contract call - * @param params Any additional parameters for the call - * @returns A TypedCallParams object for the call + * @param params Parameters for the call + * @returns An `AppClientMethodCallParams` object for the call */ - static error(args: MethodArgs<'error()void'>, params: AppClientCallCoreParams & CoreAppCallArgs) { + static error(params: CallParams & CallOnComplete): AppClientMethodCallParams & CallOnComplete { return { - method: 'error()void' as const, - methodArgs: Array.isArray(args) ? args : [], ...params, + method: 'error()void' as const, + args: Array.isArray(params.args) ? params.args : [], } } /** * Constructs a no op call for the emitSwapped(uint64,uint64)void ABI method * - * @param args Any args for the contract call - * @param params Any additional parameters for the call - * @returns A TypedCallParams object for the call + * @param params Parameters for the call + * @returns An `AppClientMethodCallParams` object for the call */ - static emitSwapped(args: MethodArgs<'emitSwapped(uint64,uint64)void'>, params: AppClientCallCoreParams & CoreAppCallArgs) { + static emitSwapped(params: CallParams & CallOnComplete): AppClientMethodCallParams & CallOnComplete { return { - method: 'emitSwapped(uint64,uint64)void' as const, - methodArgs: Array.isArray(args) ? args : [args.a, args.b], ...params, + method: 'emitSwapped(uint64,uint64)void' as const, + args: Array.isArray(params.args) ? params.args : [params.args.a, params.args.b], } } /** * Constructs a no op call for the emitSwappedTwice(uint64,uint64)void ABI method * - * @param args Any args for the contract call - * @param params Any additional parameters for the call - * @returns A TypedCallParams object for the call + * @param params Parameters for the call + * @returns An `AppClientMethodCallParams` object for the call */ - static emitSwappedTwice(args: MethodArgs<'emitSwappedTwice(uint64,uint64)void'>, params: AppClientCallCoreParams & CoreAppCallArgs) { + static emitSwappedTwice(params: CallParams & CallOnComplete): AppClientMethodCallParams & CallOnComplete { return { - method: 'emitSwappedTwice(uint64,uint64)void' as const, - methodArgs: Array.isArray(args) ? args : [args.a, args.b], ...params, + method: 'emitSwappedTwice(uint64,uint64)void' as const, + args: Array.isArray(params.args) ? params.args : [params.args.a, params.args.b], } } /** * Constructs a no op call for the emitComplex(uint64,uint64,uint32[])void ABI method * - * @param args Any args for the contract call - * @param params Any additional parameters for the call - * @returns A TypedCallParams object for the call + * @param params Parameters for the call + * @returns An `AppClientMethodCallParams` object for the call */ - static emitComplex(args: MethodArgs<'emitComplex(uint64,uint64,uint32[])void'>, params: AppClientCallCoreParams & CoreAppCallArgs) { + static emitComplex(params: CallParams & CallOnComplete): AppClientMethodCallParams & CallOnComplete { return { - method: 'emitComplex(uint64,uint64,uint32[])void' as const, - methodArgs: Array.isArray(args) ? args : [args.a, args.b, args.array], ...params, + method: 'emitComplex(uint64,uint64,uint32[])void' as const, + args: Array.isArray(params.args) ? params.args : [params.args.a, params.args.b, params.args.array], } } } /** - * A client to make calls to the TestingApp smart contract + * A factory to create and deploy one or more instance of the TestingApp smart contract and to create one or more app clients to interact with those (or other) app instances */ -export class TestingAppClient { +export class TestingAppFactory { /** - * The underlying `ApplicationClient` for when you want to have more flexibility + * The underlying `AppFactory` for when you want to have more flexibility */ - public readonly appClient: ApplicationClient - - private readonly sender: SendTransactionFrom | undefined + public readonly appFactory: _AppFactory /** - * Creates a new instance of `TestingAppClient` + * Creates a new instance of `TestingAppFactory` * - * @param appDetails appDetails The details to identify the app to deploy - * @param algod An algod client instance + * @param params The parameters to initialise the app factory with */ - constructor( - appDetails: AppDetails, - private algod: Algodv2, - ) { - this.sender = appDetails.sender - this.appClient = algokit.getAppClient( - { - ...appDetails, - app: APP_SPEC, - }, - algod, - ) + constructor(params: Omit) { + this.appFactory = new _AppFactory({ + ...params, + appSpec: APP_SPEC, + }) } - + + /** The name of the app (from the ARC-32 / ARC-56 app spec or override). */ + public get appName() { + return this.appFactory.appName + } + + /** The ARC-56 app spec being used */ + get appSpec() { + return APP_SPEC + } + + /** A reference to the underlying `AlgorandClient` this app factory is using. */ + public get algorand(): AlgorandClientInterface { + return this.appFactory.algorand + } + /** - * Checks for decode errors on the AppCallTransactionResult and maps the return value to the specified generic type + * Returns a new `AppClient` client for an app instance of the given ID. * - * @param result The AppCallTransactionResult to be mapped - * @param returnValueFormatter An optional delegate to format the return value if required - * @returns The smart contract response with an updated return value + * Automatically populates appName, defaultSender and source maps from the factory + * if not specified in the params. + * @param params The parameters to create the app client + * @returns The `AppClient` */ - protected mapReturnValue( - result: AppCallTransactionResult, - returnValueFormatter?: (value: any) => TReturn, - ): AppCallTransactionResultOfType & TResult { - if (result.return?.decodeError) { - throw result.return.decodeError - } - const returnValue = - result.return?.returnValue !== undefined && returnValueFormatter !== undefined - ? returnValueFormatter(result.return.returnValue) - : (result.return?.returnValue as TReturn | undefined) - return { ...result, return: returnValue } as AppCallTransactionResultOfType & TResult + public getAppClientById(params: AppFactoryAppClientParams) { + return new TestingAppClient(this.appFactory.getAppClientById(params)) } - + /** - * Calls the ABI method with the matching signature using an onCompletion code of NO_OP + * Returns a new `AppClient` client, resolving the app by creator address and name + * using AlgoKit app deployment semantics (i.e. looking for the app creation transaction note). * - * @param typedCallParams An object containing the method signature, args, and any other relevant parameters - * @param returnValueFormatter An optional delegate which when provided will be used to map non-undefined return values to the target type - * @returns The result of the smart contract call + * Automatically populates appName, defaultSender and source maps from the factory + * if not specified in the params. + * @param params The parameters to create the app client + * @returns The `AppClient` */ - public async call( - typedCallParams: TypedCallParams, - returnValueFormatter?: (value: any) => MethodReturn, + public async getAppClientByCreatorAndName( + params: AppFactoryResolveAppClientByCreatorAndNameParams, ) { - return this.mapReturnValue>(await this.appClient.call(typedCallParams), returnValueFormatter) + return new TestingAppClient(await this.appFactory.getAppClientByCreatorAndName(params)) } /** @@ -905,463 +530,958 @@ export class TestingAppClient { * @param params The arguments for the contract calls and any additional parameters for the call * @returns The deployment result */ - public deploy(params: TestingAppDeployArgs & AppClientDeployCoreParams = {}): ReturnType { - const createArgs = params.createCall?.(TestingAppCallFactory.create) - const updateArgs = params.updateCall?.(TestingAppCallFactory.update) - const deleteArgs = params.deleteCall?.(TestingAppCallFactory.delete) - return this.appClient.deploy({ + public async deploy(params: TestingAppDeployParams = {}) { + const result = await this.appFactory.deploy({ ...params, - updateArgs, - deleteArgs, - createArgs, - createOnCompleteAction: createArgs?.onCompleteAction, + }) + return { result: result.result, appClient: new TestingAppClient(result.appClient) } + } + + /** + * Get parameters to create transactions (create and deploy related calls) for the current app. A good mental model for this is that these parameters represent a deferred transaction creation. + */ + readonly params = { + /** + * Gets available create methods + */ + create: { + /** + * Creates a new instance of the TestingApp smart contract using a bare call. + * + * @param params The params for the bare (raw) call + * @returns The params for a create call + */ + bare: (params?: Expand) => { + return this.appFactory.params.bare.create(params) + }, + }, + + /** + * Gets available deployUpdate methods + */ + deployUpdate: { + /** + * Updates an existing instance of the TestingApp smart contract using a bare call. + * + * @param params The params for the bare (raw) call + * @returns The params for a deployUpdate call + */ + bare: (params?: Expand) => { + return this.appFactory.params.bare.deployUpdate(params) + }, + }, + + /** + * Gets available deployDelete methods + */ + deployDelete: { + /** + * Deletes an existing instance of the TestingApp smart contract using a bare call. + * + * @param params The params for the bare (raw) call + * @returns The params for a deployDelete call + */ + bare: (params?: Expand) => { + return this.appFactory.params.bare.deployDelete(params) + }, + }, + + } + + /** + * Create transactions for the current app + */ + readonly createTransaction = { + /** + * Gets available create methods + */ + create: { + /** + * Creates a new instance of the TestingApp smart contract using a bare call. + * + * @param params The params for the bare (raw) call + * @returns The transaction for a create call + */ + bare: (params?: Expand) => { + return this.appFactory.createTransaction.bare.create(params) + }, + }, + + } + + /** + * Send calls to the current app + */ + readonly send = { + /** + * Gets available create methods + */ + create: { + /** + * Creates a new instance of the TestingApp smart contract using a bare call. + * + * @param params The params for the bare (raw) call + * @returns The create result + */ + bare: async (params?: Expand) => { + const result = await this.appFactory.send.bare.create(params) + return { result: result.result, appClient: new TestingAppClient(result.appClient) } + }, + }, + + } + +} +/** + * A client to make calls to the TestingApp smart contract + */ +export class TestingAppClient { + /** + * The underlying `AppClient` for when you want to have more flexibility + */ + public readonly appClient: _AppClient + + /** + * Creates a new instance of `TestingAppClient` + * + * @param appClient An `AppClient` instance which has been created with the TestingApp app spec + */ + constructor(appClient: _AppClient) + /** + * Creates a new instance of `TestingAppClient` + * + * @param params The parameters to initialise the app client with + */ + constructor(params: Omit) + constructor(appClientOrParams: _AppClient | Omit) { + this.appClient = appClientOrParams instanceof _AppClient ? appClientOrParams : new _AppClient({ + ...appClientOrParams, + appSpec: APP_SPEC, }) } + + /** + * Checks for decode errors on the given return value and maps the return value to the return type for the given method + * @returns The typed return value or undefined if there was no value + */ + decodeReturnValue(method: TSignature, returnValue: ABIReturn | undefined) { + return returnValue !== undefined ? getArc56ReturnValue>(returnValue, this.appClient.getABIMethod(method), APP_SPEC.structs) : undefined + } + + /** + * Returns a new `TestingAppClient` client, resolving the app by creator address and name + * using AlgoKit app deployment semantics (i.e. looking for the app creation transaction note). + * @param params The parameters to create the app client + */ + public static async fromCreatorAndName(params: Omit): Promise { + return new TestingAppClient(await _AppClient.fromCreatorAndName({...params, appSpec: APP_SPEC})) + } + + /** + * Returns an `TestingAppClient` instance for the current network based on + * pre-determined network-specific app IDs specified in the ARC-56 app spec. + * + * If no IDs are in the app spec or the network isn't recognised, an error is thrown. + * @param params The parameters to create the app client + */ + static async fromNetwork( + params: Omit + ): Promise { + return new TestingAppClient(await _AppClient.fromNetwork({...params, appSpec: APP_SPEC})) + } + + /** The ID of the app instance this client is linked to. */ + public get appId() { + return this.appClient.appId + } + + /** The app address of the app instance this client is linked to. */ + public get appAddress() { + return this.appClient.appAddress + } + + /** The name of the app. */ + public get appName() { + return this.appClient.appName + } + + /** The ARC-56 app spec being used */ + public get appSpec() { + return this.appClient.appSpec + } + + /** A reference to the underlying `AlgorandClient` this app client is using. */ + public get algorand(): AlgorandClientInterface { + return this.appClient.algorand + } + + /** + * Get parameters to create transactions for the current app. A good mental model for this is that these parameters represent a deferred transaction creation. + */ + readonly params = { + /** + * Gets available update methods + */ + update: { + /** + * Updates an existing instance of the TestingApp smart contract using a bare call. + * + * @param params The params for the bare (raw) call + * @returns The update result + */ + bare: (params?: Expand) => { + return this.appClient.params.bare.update(params) + }, + }, + + /** + * Gets available delete methods + */ + delete: { + /** + * Deletes an existing instance of the TestingApp smart contract using a bare call. + * + * @param params The params for the bare (raw) call + * @returns The delete result + */ + bare: (params?: Expand) => { + return this.appClient.params.bare.delete(params) + }, + }, + + /** + * Gets available optIn methods + */ + optIn: { + /** + * Opts the user into an existing instance of the TestingApp smart contract using the `opt_in()void` ABI method. + * + * @param params The params for the smart contract call + * @returns The optIn params + */ + optIn: (params: CallParams = {args: []}) => { + return this.appClient.params.optIn(TestingAppParamsFactory.optIn.optIn(params)) + }, + + }, + + /** + * Makes a clear_state call to an existing instance of the TestingApp smart contract. + * + * @param params The params for the bare (raw) call + * @returns The clearState result + */ + clearState: (params?: Expand) => { + return this.appClient.params.bare.clearState(params) + }, + + /** + * Makes a call to the TestingApp smart contract using the `call_abi(string)string` ABI method. + * + * This method is a readonly method; calling it with onComplete of NoOp will result in a simulated transaction rather than a real transaction. + * + * @param params The params for the smart contract call + * @returns The call params + */ + callAbi: (params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + return this.appClient.params.call(TestingAppParamsFactory.callAbi(params)) + }, + + /** + * Makes a call to the TestingApp smart contract using the `call_abi_foreign_refs()string` ABI method. + * + * This method is a readonly method; calling it with onComplete of NoOp will result in a simulated transaction rather than a real transaction. + * + * @param params The params for the smart contract call + * @returns The call params + */ + callAbiForeignRefs: (params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC} = {args: []}) => { + return this.appClient.params.call(TestingAppParamsFactory.callAbiForeignRefs(params)) + }, + + /** + * Makes a call to the TestingApp smart contract using the `set_global(uint64,uint64,string,byte[4])void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call params + */ + setGlobal: (params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + return this.appClient.params.call(TestingAppParamsFactory.setGlobal(params)) + }, + + /** + * Makes a call to the TestingApp smart contract using the `set_local(uint64,uint64,string,byte[4])void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call params + */ + setLocal: (params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + return this.appClient.params.call(TestingAppParamsFactory.setLocal(params)) + }, + + /** + * Makes a call to the TestingApp smart contract using the `issue_transfer_to_sender(uint64)void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call params + */ + issueTransferToSender: (params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + return this.appClient.params.call(TestingAppParamsFactory.issueTransferToSender(params)) + }, + + /** + * Makes a call to the TestingApp smart contract using the `set_box(byte[4],string)void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call params + */ + setBox: (params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + return this.appClient.params.call(TestingAppParamsFactory.setBox(params)) + }, + + /** + * Makes a call to the TestingApp smart contract using the `error()void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call params + */ + error: (params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC} = {args: []}) => { + return this.appClient.params.call(TestingAppParamsFactory.error(params)) + }, + + /** + * Makes a call to the TestingApp smart contract using the `emitSwapped(uint64,uint64)void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call params + */ + emitSwapped: (params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + return this.appClient.params.call(TestingAppParamsFactory.emitSwapped(params)) + }, + + /** + * Makes a call to the TestingApp smart contract using the `emitSwappedTwice(uint64,uint64)void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call params + */ + emitSwappedTwice: (params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + return this.appClient.params.call(TestingAppParamsFactory.emitSwappedTwice(params)) + }, + + /** + * Makes a call to the TestingApp smart contract using the `emitComplex(uint64,uint64,uint32[])void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call params + */ + emitComplex: (params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + return this.appClient.params.call(TestingAppParamsFactory.emitComplex(params)) + }, + + } + + /** + * Create transactions for the current app + */ + readonly createTransaction = { + /** + * Gets available update methods + */ + update: { + /** + * Updates an existing instance of the TestingApp smart contract using a bare call. + * + * @param params The params for the bare (raw) call + * @returns The update result + */ + bare: (params?: Expand) => { + return this.appClient.createTransaction.bare.update(params) + }, + }, + + /** + * Gets available delete methods + */ + delete: { + /** + * Deletes an existing instance of the TestingApp smart contract using a bare call. + * + * @param params The params for the bare (raw) call + * @returns The delete result + */ + bare: (params?: Expand) => { + return this.appClient.createTransaction.bare.delete(params) + }, + }, + + /** + * Gets available optIn methods + */ + optIn: { + /** + * Opts the user into an existing instance of the TestingApp smart contract using the `opt_in()void` ABI method. + * + * @param params The params for the smart contract call + * @returns The optIn transaction + */ + optIn: (params: CallParams = {args: []}) => { + return this.appClient.createTransaction.optIn(TestingAppParamsFactory.optIn.optIn(params)) + }, + + }, + + /** + * Makes a clear_state call to an existing instance of the TestingApp smart contract. + * + * @param params The params for the bare (raw) call + * @returns The clearState result + */ + clearState: (params?: Expand) => { + return this.appClient.createTransaction.bare.clearState(params) + }, + + /** + * Makes a call to the TestingApp smart contract using the `call_abi(string)string` ABI method. + * + * This method is a readonly method; calling it with onComplete of NoOp will result in a simulated transaction rather than a real transaction. + * + * @param params The params for the smart contract call + * @returns The call transaction + */ + callAbi: (params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + return this.appClient.createTransaction.call(TestingAppParamsFactory.callAbi(params)) + }, + + /** + * Makes a call to the TestingApp smart contract using the `call_abi_foreign_refs()string` ABI method. + * + * This method is a readonly method; calling it with onComplete of NoOp will result in a simulated transaction rather than a real transaction. + * + * @param params The params for the smart contract call + * @returns The call transaction + */ + callAbiForeignRefs: (params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC} = {args: []}) => { + return this.appClient.createTransaction.call(TestingAppParamsFactory.callAbiForeignRefs(params)) + }, + + /** + * Makes a call to the TestingApp smart contract using the `set_global(uint64,uint64,string,byte[4])void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call transaction + */ + setGlobal: (params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + return this.appClient.createTransaction.call(TestingAppParamsFactory.setGlobal(params)) + }, + + /** + * Makes a call to the TestingApp smart contract using the `set_local(uint64,uint64,string,byte[4])void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call transaction + */ + setLocal: (params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + return this.appClient.createTransaction.call(TestingAppParamsFactory.setLocal(params)) + }, + + /** + * Makes a call to the TestingApp smart contract using the `issue_transfer_to_sender(uint64)void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call transaction + */ + issueTransferToSender: (params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + return this.appClient.createTransaction.call(TestingAppParamsFactory.issueTransferToSender(params)) + }, + + /** + * Makes a call to the TestingApp smart contract using the `set_box(byte[4],string)void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call transaction + */ + setBox: (params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + return this.appClient.createTransaction.call(TestingAppParamsFactory.setBox(params)) + }, + + /** + * Makes a call to the TestingApp smart contract using the `error()void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call transaction + */ + error: (params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC} = {args: []}) => { + return this.appClient.createTransaction.call(TestingAppParamsFactory.error(params)) + }, + + /** + * Makes a call to the TestingApp smart contract using the `emitSwapped(uint64,uint64)void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call transaction + */ + emitSwapped: (params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + return this.appClient.createTransaction.call(TestingAppParamsFactory.emitSwapped(params)) + }, + + /** + * Makes a call to the TestingApp smart contract using the `emitSwappedTwice(uint64,uint64)void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call transaction + */ + emitSwappedTwice: (params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + return this.appClient.createTransaction.call(TestingAppParamsFactory.emitSwappedTwice(params)) + }, + + /** + * Makes a call to the TestingApp smart contract using the `emitComplex(uint64,uint64,uint32[])void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call transaction + */ + emitComplex: (params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + return this.appClient.createTransaction.call(TestingAppParamsFactory.emitComplex(params)) + }, - /** - * Gets available create methods - */ - public get create() { - const $this = this - return { - /** - * Creates a new instance of the TestingApp smart contract using a bare call. - * - * @param args The arguments for the bare call - * @returns The create result - */ - async bare( - args: BareCallArgs & - AppClientCallCoreParams & - AppClientCompilationParams & - CoreAppCallArgs & - (OnCompleteNoOp | OnCompleteOptIn) = {}, - ) { - return $this.mapReturnValue(await $this.appClient.create(args)) - }, - } } /** - * Gets available update methods + * Send calls to the current app */ - public get update() { - const $this = this - return { + readonly send = { + /** + * Gets available update methods + */ + update: { /** * Updates an existing instance of the TestingApp smart contract using a bare call. * - * @param args The arguments for the bare call + * @param params The params for the bare (raw) call * @returns The update result */ - async bare(args: BareCallArgs & AppClientCallCoreParams & AppClientCompilationParams & CoreAppCallArgs = {}) { - return $this.mapReturnValue(await $this.appClient.update(args)) + bare: (params?: Expand) => { + return this.appClient.send.bare.update(params) }, - } - } + }, - /** - * Gets available delete methods - */ - public get delete() { - const $this = this - return { + /** + * Gets available delete methods + */ + delete: { /** * Deletes an existing instance of the TestingApp smart contract using a bare call. * - * @param args The arguments for the bare call + * @param params The params for the bare (raw) call * @returns The delete result */ - async bare(args: BareCallArgs & AppClientCallCoreParams & CoreAppCallArgs = {}) { - return $this.mapReturnValue(await $this.appClient.delete(args)) + bare: (params?: Expand) => { + return this.appClient.send.bare.delete(params) }, - } - } + }, - /** - * Gets available optIn methods - */ - public get optIn() { - const $this = this - return { + /** + * Gets available optIn methods + */ + optIn: { /** - * Opts the user into an existing instance of the TestingApp smart contract using the opt_in()void ABI method. + * Opts the user into an existing instance of the TestingApp smart contract using the `opt_in()void` ABI method. * - * @param args The arguments for the smart contract call - * @param params Any additional parameters for the call + * @param params The params for the smart contract call * @returns The optIn result */ - async optIn(args: MethodArgs<'opt_in()void'>, params: AppClientCallCoreParams = {}) { - return $this.mapReturnValue>( - await $this.appClient.optIn(TestingAppCallFactory.optIn.optIn(args, params)), - ) + optIn: async (params: CallParams & SendParams = {args: []}) => { + const result = await this.appClient.send.optIn(TestingAppParamsFactory.optIn.optIn(params)) + return {...result, return: result.return as undefined | TestingAppReturns['opt_in()void']} }, - } - } - /** - * Makes a clear_state call to an existing instance of the TestingApp smart contract. - * - * @param args The arguments for the bare call - * @returns The clear_state result - */ - public clearState(args: BareCallArgs & AppClientCallCoreParams & CoreAppCallArgs = {}) { - return this.appClient.clearState(args) - } + }, - /** - * Calls the call_abi(string)string ABI method. - * - * @param args The arguments for the contract call - * @param params Any additional parameters for the call - * @returns The result of the call - */ - public callAbi(args: MethodArgs<'call_abi(string)string'>, params: AppClientCallCoreParams & CoreAppCallArgs = {}) { - return this.call(TestingAppCallFactory.callAbi(args, params)) - } + /** + * Makes a clear_state call to an existing instance of the TestingApp smart contract. + * + * @param params The params for the bare (raw) call + * @returns The clearState result + */ + clearState: (params?: Expand) => { + return this.appClient.send.bare.clearState(params) + }, - /** - * Calls the call_abi_foreign_refs()string ABI method. - * - * @param args The arguments for the contract call - * @param params Any additional parameters for the call - * @returns The result of the call - */ - public callAbiForeignRefs(args: MethodArgs<'call_abi_foreign_refs()string'>, params: AppClientCallCoreParams & CoreAppCallArgs = {}) { - return this.call(TestingAppCallFactory.callAbiForeignRefs(args, params)) - } + /** + * Makes a call to the TestingApp smart contract using the `call_abi(string)string` ABI method. + * + * This method is a readonly method; calling it with onComplete of NoOp will result in a simulated transaction rather than a real transaction. + * + * @param params The params for the smart contract call + * @returns The call result + */ + callAbi: async (params: CallParams & SendParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + const result = await this.appClient.send.call(TestingAppParamsFactory.callAbi(params)) + return {...result, return: result.return as undefined | TestingAppReturns['call_abi(string)string']} + }, - /** - * Calls the set_global(uint64,uint64,string,byte[4])void ABI method. - * - * @param args The arguments for the contract call - * @param params Any additional parameters for the call - * @returns The result of the call - */ - public setGlobal( - args: MethodArgs<'set_global(uint64,uint64,string,byte[4])void'>, - params: AppClientCallCoreParams & CoreAppCallArgs = {}, - ) { - return this.call(TestingAppCallFactory.setGlobal(args, params)) - } + /** + * Makes a call to the TestingApp smart contract using the `call_abi_foreign_refs()string` ABI method. + * + * This method is a readonly method; calling it with onComplete of NoOp will result in a simulated transaction rather than a real transaction. + * + * @param params The params for the smart contract call + * @returns The call result + */ + callAbiForeignRefs: async (params: CallParams & SendParams & {onComplete?: OnApplicationComplete.NoOpOC} = {args: []}) => { + const result = await this.appClient.send.call(TestingAppParamsFactory.callAbiForeignRefs(params)) + return {...result, return: result.return as undefined | TestingAppReturns['call_abi_foreign_refs()string']} + }, - /** - * Calls the set_local(uint64,uint64,string,byte[4])void ABI method. - * - * @param args The arguments for the contract call - * @param params Any additional parameters for the call - * @returns The result of the call - */ - public setLocal(args: MethodArgs<'set_local(uint64,uint64,string,byte[4])void'>, params: AppClientCallCoreParams & CoreAppCallArgs = {}) { - return this.call(TestingAppCallFactory.setLocal(args, params)) - } + /** + * Makes a call to the TestingApp smart contract using the `set_global(uint64,uint64,string,byte[4])void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call result + */ + setGlobal: async (params: CallParams & SendParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + const result = await this.appClient.send.call(TestingAppParamsFactory.setGlobal(params)) + return {...result, return: result.return as undefined | TestingAppReturns['set_global(uint64,uint64,string,byte[4])void']} + }, - /** - * Calls the issue_transfer_to_sender(uint64)void ABI method. - * - * @param args The arguments for the contract call - * @param params Any additional parameters for the call - * @returns The result of the call - */ - public issueTransferToSender( - args: MethodArgs<'issue_transfer_to_sender(uint64)void'>, - params: AppClientCallCoreParams & CoreAppCallArgs = {}, - ) { - return this.call(TestingAppCallFactory.issueTransferToSender(args, params)) - } + /** + * Makes a call to the TestingApp smart contract using the `set_local(uint64,uint64,string,byte[4])void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call result + */ + setLocal: async (params: CallParams & SendParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + const result = await this.appClient.send.call(TestingAppParamsFactory.setLocal(params)) + return {...result, return: result.return as undefined | TestingAppReturns['set_local(uint64,uint64,string,byte[4])void']} + }, - /** - * Calls the set_box(byte[4],string)void ABI method. - * - * @param args The arguments for the contract call - * @param params Any additional parameters for the call - * @returns The result of the call - */ - public setBox(args: MethodArgs<'set_box(byte[4],string)void'>, params: AppClientCallCoreParams & CoreAppCallArgs = {}) { - return this.call(TestingAppCallFactory.setBox(args, params)) - } + /** + * Makes a call to the TestingApp smart contract using the `issue_transfer_to_sender(uint64)void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call result + */ + issueTransferToSender: async (params: CallParams & SendParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + const result = await this.appClient.send.call(TestingAppParamsFactory.issueTransferToSender(params)) + return {...result, return: result.return as undefined | TestingAppReturns['issue_transfer_to_sender(uint64)void']} + }, - /** - * Calls the error()void ABI method. - * - * @param args The arguments for the contract call - * @param params Any additional parameters for the call - * @returns The result of the call - */ - public error(args: MethodArgs<'error()void'>, params: AppClientCallCoreParams & CoreAppCallArgs = {}) { - return this.call(TestingAppCallFactory.error(args, params)) - } + /** + * Makes a call to the TestingApp smart contract using the `set_box(byte[4],string)void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call result + */ + setBox: async (params: CallParams & SendParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + const result = await this.appClient.send.call(TestingAppParamsFactory.setBox(params)) + return {...result, return: result.return as undefined | TestingAppReturns['set_box(byte[4],string)void']} + }, - /** - * Calls the emitSwapped(uint64,uint64)void ABI method. - * - * @param args The arguments for the contract call - * @param params Any additional parameters for the call - * @returns The result of the call - */ - public emitSwapped(args: MethodArgs<'emitSwapped(uint64,uint64)void'>, params: AppClientCallCoreParams & CoreAppCallArgs = {}) { - return this.call(TestingAppCallFactory.emitSwapped(args, params)) - } + /** + * Makes a call to the TestingApp smart contract using the `error()void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call result + */ + error: async (params: CallParams & SendParams & {onComplete?: OnApplicationComplete.NoOpOC} = {args: []}) => { + const result = await this.appClient.send.call(TestingAppParamsFactory.error(params)) + return {...result, return: result.return as undefined | TestingAppReturns['error()void']} + }, - /** - * Calls the emitSwappedTwice(uint64,uint64)void ABI method. - * - * @param args The arguments for the contract call - * @param params Any additional parameters for the call - * @returns The result of the call - */ - public emitSwappedTwice(args: MethodArgs<'emitSwappedTwice(uint64,uint64)void'>, params: AppClientCallCoreParams & CoreAppCallArgs = {}) { - return this.call(TestingAppCallFactory.emitSwappedTwice(args, params)) - } + /** + * Makes a call to the TestingApp smart contract using the `emitSwapped(uint64,uint64)void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call result + */ + emitSwapped: async (params: CallParams & SendParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + const result = await this.appClient.send.call(TestingAppParamsFactory.emitSwapped(params)) + return {...result, return: result.return as undefined | TestingAppReturns['emitSwapped(uint64,uint64)void']} + }, + + /** + * Makes a call to the TestingApp smart contract using the `emitSwappedTwice(uint64,uint64)void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call result + */ + emitSwappedTwice: async (params: CallParams & SendParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + const result = await this.appClient.send.call(TestingAppParamsFactory.emitSwappedTwice(params)) + return {...result, return: result.return as undefined | TestingAppReturns['emitSwappedTwice(uint64,uint64)void']} + }, + + /** + * Makes a call to the TestingApp smart contract using the `emitComplex(uint64,uint64,uint32[])void` ABI method. + * + * @param params The params for the smart contract call + * @returns The call result + */ + emitComplex: async (params: CallParams & SendParams & {onComplete?: OnApplicationComplete.NoOpOC}) => { + const result = await this.appClient.send.call(TestingAppParamsFactory.emitComplex(params)) + return {...result, return: result.return as undefined | TestingAppReturns['emitComplex(uint64,uint64,uint32[])void']} + }, - /** - * Calls the emitComplex(uint64,uint64,uint32[])void ABI method. - * - * @param args The arguments for the contract call - * @param params Any additional parameters for the call - * @returns The result of the call - */ - public emitComplex(args: MethodArgs<'emitComplex(uint64,uint64,uint32[])void'>, params: AppClientCallCoreParams & CoreAppCallArgs = {}) { - return this.call(TestingAppCallFactory.emitComplex(args, params)) } /** - * Extracts a binary state value out of an AppState dictionary + * Clone this app client with different params * - * @param state The state dictionary containing the state value - * @param key The key of the state value - * @returns A BinaryState instance containing the state value, or undefined if the key was not found + * @param params The params to use for the the cloned app client. Omit a param to keep the original value. Set a param to override the original value. Setting to undefined will clear the original value. + * @returns A new app client with the altered params */ - private static getBinaryState(state: AppState, key: string): BinaryState | undefined { - const value = state[key] - if (!value) return undefined - if (!('valueRaw' in value)) throw new Error(`Failed to parse state value for ${key}; received an int when expected a byte array`) - return { - asString(): string { - return value.value - }, - asByteArray(): Uint8Array { - return value.valueRaw - }, - } + public clone(params: CloneAppClientParams) { + return new TestingAppClient(this.appClient.clone(params)) } /** - * Extracts a integer state value out of an AppState dictionary + * Makes a readonly (simulated) call to the TestingApp smart contract using the `call_abi(string)string` ABI method. + * + * This method is a readonly method; calling it with onComplete of NoOp will result in a simulated transaction rather than a real transaction. * - * @param state The state dictionary containing the state value - * @param key The key of the state value - * @returns An IntegerState instance containing the state value, or undefined if the key was not found + * @param params The params for the smart contract call + * @returns The call result */ - private static getIntegerState(state: AppState, key: string): IntegerState | undefined { - const value = state[key] - if (!value) return undefined - if ('valueRaw' in value) throw new Error(`Failed to parse state value for ${key}; received a byte array when expected a number`) - return { - asBigInt() { - return typeof value.value === 'bigint' ? value.value : BigInt(value.value) - }, - asNumber(): number { - return typeof value.value === 'bigint' ? Number(value.value) : value.value - }, - } + async callAbi(params: CallParams) { + const result = await this.appClient.send.call(TestingAppParamsFactory.callAbi(params)) + return result.return as TestingAppReturns['call_abi(string)string'] } /** - * Returns the smart contract's global state wrapped in a strongly typed accessor with options to format the stored value + * Makes a readonly (simulated) call to the TestingApp smart contract using the `call_abi_foreign_refs()string` ABI method. + * + * This method is a readonly method; calling it with onComplete of NoOp will result in a simulated transaction rather than a real transaction. + * + * @param params The params for the smart contract call + * @returns The call result */ - public async getGlobalState(): Promise { - const state = await this.appClient.getGlobalState() - return { - get bytes1() { - return TestingAppClient.getBinaryState(state, 'bytes1') - }, - get bytes2() { - return TestingAppClient.getBinaryState(state, 'bytes2') - }, - get int1() { - return TestingAppClient.getIntegerState(state, 'int1') - }, - get int2() { - return TestingAppClient.getIntegerState(state, 'int2') - }, - get value() { - return TestingAppClient.getIntegerState(state, 'value') - }, - } + async callAbiForeignRefs(params: CallParams = {args: []}) { + const result = await this.appClient.send.call(TestingAppParamsFactory.callAbiForeignRefs(params)) + return result.return as TestingAppReturns['call_abi_foreign_refs()string'] } /** - * Returns the smart contract's local state wrapped in a strongly typed accessor with options to format the stored value - * - * @param account The address of the account for which to read local state from + * Methods to access state for the current TestingApp app */ - public async getLocalState(account: string | SendTransactionFrom): Promise { - const state = await this.appClient.getLocalState(account) - return { - get local_bytes1() { - return TestingAppClient.getBinaryState(state, 'local_bytes1') - }, - get local_bytes2() { - return TestingAppClient.getBinaryState(state, 'local_bytes2') - }, - get local_int1() { - return TestingAppClient.getIntegerState(state, 'local_int1') - }, - get local_int2() { - return TestingAppClient.getIntegerState(state, 'local_int2') + state = { + /** + * Methods to access global state for the current TestingApp app + */ + global: { + /** + * Get all current keyed values from global state + */ + getAll: async (): Promise>> => { + const result = await this.appClient.state.global.getAll() + return { + bytes1: new BinaryStateValue(result.bytes1), + bytes2: new BinaryStateValue(result.bytes2), + int1: result.int1, + int2: result.int2, + value: result.value, + } }, - } + /** + * Get the current value of the bytes1 key in global state + */ + bytes1: async (): Promise => { return new BinaryStateValue((await this.appClient.state.global.getValue("bytes1")) as Uint8Array | undefined) }, + /** + * Get the current value of the bytes2 key in global state + */ + bytes2: async (): Promise => { return new BinaryStateValue((await this.appClient.state.global.getValue("bytes2")) as Uint8Array | undefined) }, + /** + * Get the current value of the int1 key in global state + */ + int1: async (): Promise => { return (await this.appClient.state.global.getValue("int1")) as bigint | undefined }, + /** + * Get the current value of the int2 key in global state + */ + int2: async (): Promise => { return (await this.appClient.state.global.getValue("int2")) as bigint | undefined }, + /** + * Get the current value of the value key in global state + */ + value: async (): Promise => { return (await this.appClient.state.global.getValue("value")) as bigint | undefined }, + }, + /** + * Methods to access local state for the current TestingApp app + */ + local: (address: string | Address) => { + const encodedAddress = typeof address === 'string' ? address : encodeAddress(address.publicKey) + return { + /** + * Get all current keyed values from local state + */ + getAll: async (): Promise>> => { + const result = await this.appClient.state.local(encodedAddress).getAll() + return { + localBytes1: new BinaryStateValue(result.local_bytes1), + localBytes2: new BinaryStateValue(result.local_bytes2), + localInt1: result.local_int1, + localInt2: result.local_int2, + } + }, + /** + * Get the current value of the local_bytes1 key in local state + */ + localBytes1: async (): Promise => { return new BinaryStateValue((await this.appClient.state.local(encodedAddress).getValue("localBytes1")) as Uint8Array | undefined) }, + /** + * Get the current value of the local_bytes2 key in local state + */ + localBytes2: async (): Promise => { return new BinaryStateValue((await this.appClient.state.local(encodedAddress).getValue("localBytes2")) as Uint8Array | undefined) }, + /** + * Get the current value of the local_int1 key in local state + */ + localInt1: async (): Promise => { return (await this.appClient.state.local(encodedAddress).getValue("localInt1")) as bigint | undefined }, + /** + * Get the current value of the local_int2 key in local state + */ + localInt2: async (): Promise => { return (await this.appClient.state.local(encodedAddress).getValue("localInt2")) as bigint | undefined }, + } + }, } - public compose(): TestingAppComposer { + public newGroup(): TestingAppComposer { const client = this - const atc = new AtomicTransactionComposer() - let promiseChain: Promise = Promise.resolve() - const resultMappers: Array any)> = [] + const composer = this.algorand.newGroup() + let promiseChain:Promise = Promise.resolve() + const resultMappers: Array any)> = [] return { - callAbi(args: MethodArgs<'call_abi(string)string'>, params?: AppClientCallCoreParams & CoreAppCallArgs) { - promiseChain = promiseChain.then(() => - client.callAbi(args, { ...params, sendParams: { ...params?.sendParams, skipSending: true, atc } }), - ) - resultMappers.push(undefined) + /** + * Add a call_abi(string)string method call against the TestingApp contract + */ + callAbi(params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) { + promiseChain = promiseChain.then(async () => composer.addAppCallMethodCall(await client.params.callAbi(params))) + resultMappers.push((v) => client.decodeReturnValue('call_abi(string)string', v)) return this }, - callAbiForeignRefs(args: MethodArgs<'call_abi_foreign_refs()string'>, params?: AppClientCallCoreParams & CoreAppCallArgs) { - promiseChain = promiseChain.then(() => - client.callAbiForeignRefs(args, { ...params, sendParams: { ...params?.sendParams, skipSending: true, atc } }), - ) - resultMappers.push(undefined) + /** + * Add a call_abi_foreign_refs()string method call against the TestingApp contract + */ + callAbiForeignRefs(params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) { + promiseChain = promiseChain.then(async () => composer.addAppCallMethodCall(await client.params.callAbiForeignRefs(params))) + resultMappers.push((v) => client.decodeReturnValue('call_abi_foreign_refs()string', v)) return this }, - setGlobal(args: MethodArgs<'set_global(uint64,uint64,string,byte[4])void'>, params?: AppClientCallCoreParams & CoreAppCallArgs) { - promiseChain = promiseChain.then(() => - client.setGlobal(args, { ...params, sendParams: { ...params?.sendParams, skipSending: true, atc } }), - ) + /** + * Add a set_global(uint64,uint64,string,byte[4])void method call against the TestingApp contract + */ + setGlobal(params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) { + promiseChain = promiseChain.then(async () => composer.addAppCallMethodCall(await client.params.setGlobal(params))) resultMappers.push(undefined) return this }, - setLocal(args: MethodArgs<'set_local(uint64,uint64,string,byte[4])void'>, params?: AppClientCallCoreParams & CoreAppCallArgs) { - promiseChain = promiseChain.then(() => - client.setLocal(args, { ...params, sendParams: { ...params?.sendParams, skipSending: true, atc } }), - ) + /** + * Add a set_local(uint64,uint64,string,byte[4])void method call against the TestingApp contract + */ + setLocal(params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) { + promiseChain = promiseChain.then(async () => composer.addAppCallMethodCall(await client.params.setLocal(params))) resultMappers.push(undefined) return this }, - issueTransferToSender(args: MethodArgs<'issue_transfer_to_sender(uint64)void'>, params?: AppClientCallCoreParams & CoreAppCallArgs) { - promiseChain = promiseChain.then(() => - client.issueTransferToSender(args, { ...params, sendParams: { ...params?.sendParams, skipSending: true, atc } }), - ) + /** + * Add a issue_transfer_to_sender(uint64)void method call against the TestingApp contract + */ + issueTransferToSender(params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) { + promiseChain = promiseChain.then(async () => composer.addAppCallMethodCall(await client.params.issueTransferToSender(params))) resultMappers.push(undefined) return this }, - setBox(args: MethodArgs<'set_box(byte[4],string)void'>, params?: AppClientCallCoreParams & CoreAppCallArgs) { - promiseChain = promiseChain.then(() => - client.setBox(args, { ...params, sendParams: { ...params?.sendParams, skipSending: true, atc } }), - ) + /** + * Add a set_box(byte[4],string)void method call against the TestingApp contract + */ + setBox(params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) { + promiseChain = promiseChain.then(async () => composer.addAppCallMethodCall(await client.params.setBox(params))) resultMappers.push(undefined) return this }, - error(args: MethodArgs<'error()void'>, params?: AppClientCallCoreParams & CoreAppCallArgs) { - promiseChain = promiseChain.then(() => - client.error(args, { ...params, sendParams: { ...params?.sendParams, skipSending: true, atc } }), - ) + /** + * Add a error()void method call against the TestingApp contract + */ + error(params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) { + promiseChain = promiseChain.then(async () => composer.addAppCallMethodCall(await client.params.error(params))) resultMappers.push(undefined) return this }, - emitSwapped(args: MethodArgs<'emitSwapped(uint64,uint64)void'>, params?: AppClientCallCoreParams & CoreAppCallArgs) { - promiseChain = promiseChain.then(() => - client.emitSwapped(args, { ...params, sendParams: { ...params?.sendParams, skipSending: true, atc } }), - ) + /** + * Add a emitSwapped(uint64,uint64)void method call against the TestingApp contract + */ + emitSwapped(params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) { + promiseChain = promiseChain.then(async () => composer.addAppCallMethodCall(await client.params.emitSwapped(params))) resultMappers.push(undefined) return this }, - emitSwappedTwice(args: MethodArgs<'emitSwappedTwice(uint64,uint64)void'>, params?: AppClientCallCoreParams & CoreAppCallArgs) { - promiseChain = promiseChain.then(() => - client.emitSwappedTwice(args, { ...params, sendParams: { ...params?.sendParams, skipSending: true, atc } }), - ) + /** + * Add a emitSwappedTwice(uint64,uint64)void method call against the TestingApp contract + */ + emitSwappedTwice(params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) { + promiseChain = promiseChain.then(async () => composer.addAppCallMethodCall(await client.params.emitSwappedTwice(params))) resultMappers.push(undefined) return this }, - emitComplex(args: MethodArgs<'emitComplex(uint64,uint64,uint32[])void'>, params?: AppClientCallCoreParams & CoreAppCallArgs) { - promiseChain = promiseChain.then(() => - client.emitComplex(args, { ...params, sendParams: { ...params?.sendParams, skipSending: true, atc } }), - ) + /** + * Add a emitComplex(uint64,uint64,uint32[])void method call against the TestingApp contract + */ + emitComplex(params: CallParams & {onComplete?: OnApplicationComplete.NoOpOC}) { + promiseChain = promiseChain.then(async () => composer.addAppCallMethodCall(await client.params.emitComplex(params))) resultMappers.push(undefined) return this }, get update() { - const $this = this return { - bare(args?: BareCallArgs & AppClientCallCoreParams & AppClientCompilationParams & CoreAppCallArgs) { - promiseChain = promiseChain.then(() => - client.update.bare({ ...args, sendParams: { ...args?.sendParams, skipSending: true, atc } }), - ) - resultMappers.push(undefined) - return $this + bare: (params?: AppClientBareCallParams & AppClientCompilationParams ) => { + promiseChain = promiseChain.then(async () => composer.addAppUpdate(await client.params.update.bare(params))) + return this }, } }, get delete() { - const $this = this return { - bare(args?: BareCallArgs & AppClientCallCoreParams & CoreAppCallArgs) { - promiseChain = promiseChain.then(() => - client.delete.bare({ ...args, sendParams: { ...args?.sendParams, skipSending: true, atc } }), - ) - resultMappers.push(undefined) - return $this + bare: (params?: AppClientBareCallParams ) => { + promiseChain = promiseChain.then(() => composer.addAppDelete(client.params.delete.bare(params))) + return this }, } }, get optIn() { - const $this = this return { - optIn(args: MethodArgs<'opt_in()void'>, params?: AppClientCallCoreParams) { - promiseChain = promiseChain.then(() => - client.optIn.optIn(args, { ...params, sendParams: { ...params?.sendParams, skipSending: true, atc } }), - ) + optIn: (params: CallParams) => { + promiseChain = promiseChain.then(async () => composer.addAppCallMethodCall(await client.params.optIn.optIn(params))) resultMappers.push(undefined) - return $this + return this }, } }, - clearState(args?: BareCallArgs & AppClientCallCoreParams & CoreAppCallArgs) { - promiseChain = promiseChain.then(() => client.clearState({ ...args, sendParams: { ...args?.sendParams, skipSending: true, atc } })) - resultMappers.push(undefined) + /** + * Add a clear state call to the TestingApp contract + */ + clearState(params: AppClientBareCallParams) { + promiseChain = promiseChain.then(() => composer.addAppCall(client.params.clearState(params))) return this }, - addTransaction( - txn: TransactionWithSigner | TransactionToSign | Transaction | Promise, - defaultSender?: SendTransactionFrom, - ) { - promiseChain = promiseChain.then(async () => - atc.addTransaction(await algokit.getTransactionWithSigner(txn, defaultSender ?? client.sender)), - ) + addTransaction(txn: Transaction, signer?: TransactionSigner) { + promiseChain = promiseChain.then(() => composer.addTransaction(txn, signer)) return this }, - async atc() { + async composer() { await promiseChain - return atc + return composer }, async simulate(options?: SimulateOptions) { await promiseChain - const result = await atc.simulate(client.algod, new modelsv2.SimulateRequest({ txnGroups: [], ...options })) + const result = await composer.simulate(options) return { ...result, - returns: result.methodResults?.map((val, i) => - resultMappers[i] !== undefined ? resultMappers[i]!(val.returnValue) : val.returnValue, - ), + returns: result.returns?.map((val, i) => resultMappers[i] !== undefined ? resultMappers[i]!(val) : val.returnValue) } }, - async execute() { + async send(params?: SendParams) { await promiseChain - const result = await algokit.sendAtomicTransactionComposer({ atc, sendParams: {} }, client.algod) + const result = await composer.send(params) return { ...result, - returns: result.returns?.map((val, i) => (resultMappers[i] !== undefined ? resultMappers[i]!(val.returnValue) : val.returnValue)), + returns: result.returns?.map((val, i) => resultMappers[i] !== undefined ? resultMappers[i]!(val) : val.returnValue) } - }, + } } as unknown as TestingAppComposer } } @@ -1373,10 +1493,7 @@ export type TestingAppComposer = { * @param params Any additional parameters for the call * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions */ - callAbi( - args: MethodArgs<'call_abi(string)string'>, - params?: AppClientCallCoreParams & CoreAppCallArgs, - ): TestingAppComposer<[...TReturns, MethodReturn<'call_abi(string)string'>]> + callAbi(params?: CallParams): TestingAppComposer<[...TReturns, TestingAppReturns['call_abi(string)string'] | undefined]> /** * Calls the call_abi_foreign_refs()string ABI method. @@ -1385,10 +1502,7 @@ export type TestingAppComposer = { * @param params Any additional parameters for the call * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions */ - callAbiForeignRefs( - args: MethodArgs<'call_abi_foreign_refs()string'>, - params?: AppClientCallCoreParams & CoreAppCallArgs, - ): TestingAppComposer<[...TReturns, MethodReturn<'call_abi_foreign_refs()string'>]> + callAbiForeignRefs(params?: CallParams): TestingAppComposer<[...TReturns, TestingAppReturns['call_abi_foreign_refs()string'] | undefined]> /** * Calls the set_global(uint64,uint64,string,byte[4])void ABI method. @@ -1397,10 +1511,7 @@ export type TestingAppComposer = { * @param params Any additional parameters for the call * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions */ - setGlobal( - args: MethodArgs<'set_global(uint64,uint64,string,byte[4])void'>, - params?: AppClientCallCoreParams & CoreAppCallArgs, - ): TestingAppComposer<[...TReturns, MethodReturn<'set_global(uint64,uint64,string,byte[4])void'>]> + setGlobal(params?: CallParams): TestingAppComposer<[...TReturns, TestingAppReturns['set_global(uint64,uint64,string,byte[4])void'] | undefined]> /** * Calls the set_local(uint64,uint64,string,byte[4])void ABI method. @@ -1409,10 +1520,7 @@ export type TestingAppComposer = { * @param params Any additional parameters for the call * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions */ - setLocal( - args: MethodArgs<'set_local(uint64,uint64,string,byte[4])void'>, - params?: AppClientCallCoreParams & CoreAppCallArgs, - ): TestingAppComposer<[...TReturns, MethodReturn<'set_local(uint64,uint64,string,byte[4])void'>]> + setLocal(params?: CallParams): TestingAppComposer<[...TReturns, TestingAppReturns['set_local(uint64,uint64,string,byte[4])void'] | undefined]> /** * Calls the issue_transfer_to_sender(uint64)void ABI method. @@ -1421,10 +1529,7 @@ export type TestingAppComposer = { * @param params Any additional parameters for the call * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions */ - issueTransferToSender( - args: MethodArgs<'issue_transfer_to_sender(uint64)void'>, - params?: AppClientCallCoreParams & CoreAppCallArgs, - ): TestingAppComposer<[...TReturns, MethodReturn<'issue_transfer_to_sender(uint64)void'>]> + issueTransferToSender(params?: CallParams): TestingAppComposer<[...TReturns, TestingAppReturns['issue_transfer_to_sender(uint64)void'] | undefined]> /** * Calls the set_box(byte[4],string)void ABI method. @@ -1433,10 +1538,7 @@ export type TestingAppComposer = { * @param params Any additional parameters for the call * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions */ - setBox( - args: MethodArgs<'set_box(byte[4],string)void'>, - params?: AppClientCallCoreParams & CoreAppCallArgs, - ): TestingAppComposer<[...TReturns, MethodReturn<'set_box(byte[4],string)void'>]> + setBox(params?: CallParams): TestingAppComposer<[...TReturns, TestingAppReturns['set_box(byte[4],string)void'] | undefined]> /** * Calls the error()void ABI method. @@ -1445,10 +1547,7 @@ export type TestingAppComposer = { * @param params Any additional parameters for the call * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions */ - error( - args: MethodArgs<'error()void'>, - params?: AppClientCallCoreParams & CoreAppCallArgs, - ): TestingAppComposer<[...TReturns, MethodReturn<'error()void'>]> + error(params?: CallParams): TestingAppComposer<[...TReturns, TestingAppReturns['error()void'] | undefined]> /** * Calls the emitSwapped(uint64,uint64)void ABI method. @@ -1457,10 +1556,7 @@ export type TestingAppComposer = { * @param params Any additional parameters for the call * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions */ - emitSwapped( - args: MethodArgs<'emitSwapped(uint64,uint64)void'>, - params?: AppClientCallCoreParams & CoreAppCallArgs, - ): TestingAppComposer<[...TReturns, MethodReturn<'emitSwapped(uint64,uint64)void'>]> + emitSwapped(params?: CallParams): TestingAppComposer<[...TReturns, TestingAppReturns['emitSwapped(uint64,uint64)void'] | undefined]> /** * Calls the emitSwappedTwice(uint64,uint64)void ABI method. @@ -1469,10 +1565,7 @@ export type TestingAppComposer = { * @param params Any additional parameters for the call * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions */ - emitSwappedTwice( - args: MethodArgs<'emitSwappedTwice(uint64,uint64)void'>, - params?: AppClientCallCoreParams & CoreAppCallArgs, - ): TestingAppComposer<[...TReturns, MethodReturn<'emitSwappedTwice(uint64,uint64)void'>]> + emitSwappedTwice(params?: CallParams): TestingAppComposer<[...TReturns, TestingAppReturns['emitSwappedTwice(uint64,uint64)void'] | undefined]> /** * Calls the emitComplex(uint64,uint64,uint32[])void ABI method. @@ -1481,25 +1574,7 @@ export type TestingAppComposer = { * @param params Any additional parameters for the call * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions */ - emitComplex( - args: MethodArgs<'emitComplex(uint64,uint64,uint32[])void'>, - params?: AppClientCallCoreParams & CoreAppCallArgs, - ): TestingAppComposer<[...TReturns, MethodReturn<'emitComplex(uint64,uint64,uint32[])void'>]> - - /** - * Gets available update methods - */ - readonly update: { - /** - * Updates an existing instance of the TestingApp smart contract using a bare call. - * - * @param args The arguments for the bare call - * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions - */ - bare( - args?: BareCallArgs & AppClientCallCoreParams & AppClientCompilationParams & CoreAppCallArgs, - ): TestingAppComposer<[...TReturns, undefined]> - } + emitComplex(params?: CallParams): TestingAppComposer<[...TReturns, TestingAppReturns['emitComplex(uint64,uint64,uint32[])void'] | undefined]> /** * Gets available delete methods @@ -1511,7 +1586,7 @@ export type TestingAppComposer = { * @param args The arguments for the bare call * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions */ - bare(args?: BareCallArgs & AppClientCallCoreParams & CoreAppCallArgs): TestingAppComposer<[...TReturns, undefined]> + bare(params?: AppClientBareCallParams ): TestingAppComposer<[...TReturns, undefined]> } /** @@ -1525,10 +1600,7 @@ export type TestingAppComposer = { * @param params Any additional parameters for the call * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions */ - optIn( - args: MethodArgs<'opt_in()void'>, - params?: AppClientCallCoreParams, - ): TestingAppComposer<[...TReturns, MethodReturn<'opt_in()void'>]> + optIn(params?: CallParams): TestingAppComposer<[...TReturns, TestingAppReturns['opt_in()void'] | undefined]> } /** @@ -1537,40 +1609,29 @@ export type TestingAppComposer = { * @param args The arguments for the bare call * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions */ - clearState(args?: BareCallArgs & AppClientCallCoreParams & CoreAppCallArgs): TestingAppComposer<[...TReturns, undefined]> + clearState(params?: AppClientBareCallParams): TestingAppComposer<[...TReturns, undefined]> /** * Adds a transaction to the composer * - * @param txn One of: A TransactionWithSigner object (returned as is), a TransactionToSign object (signer is obtained from the signer property), a Transaction object (signer is extracted from the defaultSender parameter), an async SendTransactionResult returned by one of algokit utils helpers (signer is obtained from the defaultSender parameter) - * @param defaultSender The default sender to be used to obtain a signer where the object provided to the transaction parameter does not include a signer. + * @param txn A transaction to add to the transaction group + * @param signer The optional signer to use when signing this transaction. */ - addTransaction( - txn: TransactionWithSigner | TransactionToSign | Transaction | Promise, - defaultSender?: SendTransactionFrom, - ): TestingAppComposer + addTransaction(txn: Transaction, signer?: TransactionSigner): TestingAppComposer /** * Returns the underlying AtomicTransactionComposer instance */ - atc(): Promise + composer(): TransactionComposer /** * Simulates the transaction group and returns the result */ - simulate(options?: SimulateOptions): Promise> + simulate(options?: SimulateOptions): Promise & { simulateResponse: SimulateResponse }> /** - * Executes the transaction group and returns the results + * Sends the transaction group to the network and returns the results */ - execute(): Promise> + send(params?: SendParams): Promise> } -export type SimulateOptions = Omit[0], 'txnGroups'> -export type TestingAppComposerSimulateResult = { +export type TestingAppComposerResults = Expand = { - returns: TReturns - groupId: string - txIds: string[] - transactions: Transaction[] -} +}> + diff --git a/tests/contract/contract.ts b/tests/contract/contract.ts index 2b244de..ae994df 100644 --- a/tests/contract/contract.ts +++ b/tests/contract/contract.ts @@ -1,7 +1,8 @@ -import * as algokit from '@algorandfoundation/algokit-utils' import { APP_DEPLOY_NOTE_DAPP, AppDeployMetadata, OnSchemaBreak, OnUpdate } from '@algorandfoundation/algokit-utils/types/app' +import { AppManager } from '@algorandfoundation/algokit-utils/types/app-manager' import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' -import { Arc2TransactionNote, SendTransactionFrom } from '@algorandfoundation/algokit-utils/types/transaction' +import { TransactionComposer } from '@algorandfoundation/algokit-utils/types/composer' +import { SendTransactionFrom } from '@algorandfoundation/algokit-utils/types/transaction' import { readFile } from 'fs/promises' import path from 'path' @@ -26,14 +27,14 @@ export const getTestingAppCreateParams = async (from: SendTransactionFrom, metad const contract = await getTestingAppContract() return { from: from, - approvalProgram: algokit.replaceDeployTimeControlParams(contract.approvalProgram, metadata).replace('TMPL_VALUE', '1'), + approvalProgram: AppManager.replaceTealTemplateDeployTimeControlParams(contract.approvalProgram, metadata).replace('TMPL_VALUE', '1'), clearStateProgram: contract.clearStateProgram, schema: contract.stateSchema, - note: algokit.encodeTransactionNote({ + note: TransactionComposer.arc2Note({ dAppName: APP_DEPLOY_NOTE_DAPP, data: metadata, format: 'j', - } as Arc2TransactionNote), + }), } } diff --git a/tests/contract/poetry.lock b/tests/contract/poetry.lock index 5b8af7a..cabab32 100644 --- a/tests/contract/poetry.lock +++ b/tests/contract/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. [[package]] name = "algokit-utils" @@ -541,6 +541,26 @@ files = [ dev = ["Django (>=1.11)", "check-manifest", "colorama (<=0.4.1)", "coverage", "flake8", "nose2", "readme-renderer (<25.0)", "tox", "wheel", "zest.releaser[recommended]"] doc = ["Sphinx", "sphinx-rtd-theme"] +[[package]] +name = "setuptools" +version = "75.6.0" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +optional = false +python-versions = ">=3.9" +files = [ + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, +] + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] + [[package]] name = "sniffio" version = "1.3.0" @@ -670,4 +690,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "f17fbf55d503c87959b8b624aca1487e3393d21f138bdac15f98d4acae527fb3" +content-hash = "3694305770cc2cea13f81c614eebc3958c830bf6f2cbc11b5adda6421feb1a39" diff --git a/tests/contract/pyproject.toml b/tests/contract/pyproject.toml index bf5db5f..304ea89 100644 --- a/tests/contract/pyproject.toml +++ b/tests/contract/pyproject.toml @@ -8,6 +8,7 @@ authors = ["Rob Moore "] python = "^3.10" beaker-pyteal = "^1.1.1" algokit-utils = "^2.1.2" +setuptools = "^75.6.0" [tool.poetry.group.dev.dependencies] ruff = "^0.1.6" diff --git a/tests/filterFixture.ts b/tests/filterFixture.ts index 609405f..cda642c 100644 --- a/tests/filterFixture.ts +++ b/tests/filterFixture.ts @@ -21,7 +21,7 @@ export function filterFixture(fixtureConfig?: AlgorandFixtureConfig) { filters: filter, arc28Events, }, - localnet.context.algod, + localnet.algorand, ) return subscribed } @@ -29,7 +29,7 @@ export function filterFixture(fixtureConfig?: AlgorandFixtureConfig) { const subscribeIndexer = async (filter: TransactionFilter, result: SendTransactionResult, arc28Events?: Arc28EventGroup[]) => { const start = +new Date() // Ensure there is another transaction so algod subscription can process something - await SendXTransactions(2, systemAccount, localnet.context.algod) + await SendXTransactions(2, systemAccount, localnet.algorand) // Wait for indexer to catch up await localnet.context.waitForIndexerTransaction(result.transaction.txID()) const durationInSeconds = (+new Date() - start) / 1000 @@ -46,8 +46,7 @@ export function filterFixture(fixtureConfig?: AlgorandFixtureConfig) { filters: filter, arc28Events, }, - localnet.context.algod, - localnet.context.indexer, + localnet.algorand, ) return subscribed } diff --git a/tests/scenarios/app-call-transactions.spec.ts b/tests/scenarios/app-call-transactions.spec.ts index 69bd9ab..2749a59 100644 --- a/tests/scenarios/app-call-transactions.spec.ts +++ b/tests/scenarios/app-call-transactions.spec.ts @@ -1,7 +1,6 @@ import { algorandFixture } from '@algorandfoundation/algokit-utils/testing' -import { Account } from 'algosdk' import { afterEach, beforeEach, describe, expect, test, vitest } from 'vitest' -import { TestingAppClient } from '../contract/client' +import { app } from '../testing-app' import { GetSubscribedTransactions, SendXTransactions } from '../transactions' describe('App call transactions', () => { @@ -12,33 +11,12 @@ describe('App call transactions', () => { }) describe('Can have an app create transaction subscribed correctly from algod', () => { - const app = async (config: { create: boolean }, creator: Account) => { - const app = new TestingAppClient( - { - resolveBy: 'id', - id: 0, - }, - localnet.context.algod, - ) - const creation = await app.create.bare({ - sender: creator, - sendParams: { - skipSending: !config.create, - }, - }) - - return { - app, - creation, - } - } - test('Works for app create', async () => { const { testAccount } = localnet.context - const app1 = await app({ create: true }, testAccount) + const app1 = await app({ create: true, algorand: localnet.algorand, creator: testAccount }) // Ensure there is another transaction so algod subscription can process something - await SendXTransactions(1, testAccount, localnet.context.algod) + await SendXTransactions(1, testAccount, localnet.algorand) // Wait for indexer to catch up await localnet.context.waitForIndexer() @@ -47,11 +25,11 @@ describe('App call transactions', () => { { roundsToSync: 1, syncBehaviour: 'sync-oldest', - watermark: Number(app1.creation.confirmation?.confirmedRound) - 1, - currentRound: Number(app1.creation.confirmation?.confirmedRound), + watermark: Number(app1.result.confirmation?.confirmedRound) - 1, + currentRound: Number(app1.result.confirmation?.confirmedRound), filters: { appCreate: true }, }, - localnet.context.algod, + localnet.algorand, ), ]) diff --git a/tests/scenarios/balance-changes.spec.ts b/tests/scenarios/balance-changes.spec.ts index 916b981..1a48fb9 100644 --- a/tests/scenarios/balance-changes.spec.ts +++ b/tests/scenarios/balance-changes.spec.ts @@ -1,5 +1,5 @@ -import * as algokit from '@algorandfoundation/algokit-utils' -import algosdk, { SuggestedParams } from 'algosdk' +import { microAlgo } from '@algorandfoundation/algokit-utils' +import { AlgoAmount } from '@algorandfoundation/algokit-utils/types/amount' import invariant from 'tiny-invariant' import { afterEach, beforeAll, beforeEach, describe, expect, test } from 'vitest' import { BalanceChangeRole } from '../../src/types' @@ -20,77 +20,63 @@ describe('Subscribing to calls that effect balance changes', () => { beforeAll(hooks.beforeAll, 10_000) beforeEach(hooks.beforeEach, 10_000) afterEach(hooks.afterEach) - const acfgCreate = (params: SuggestedParams, from: string, fee: number, total?: bigint | number) => { - params.fee = fee - params.flatFee = true - return algosdk.makeAssetCreateTxnWithSuggestedParamsFromObject({ - suggestedParams: params, - from, + const acfgCreate = (sender: string, fee: AlgoAmount, total?: bigint) => { + return localnet.algorand.createTransaction.assetCreate({ + sender, decimals: 0, - total: total ?? 100, + total: total ?? 100n, defaultFrozen: false, - clawback: from, - manager: from, + clawback: sender, + manager: sender, + staticFee: fee, }) } - const acfgDestroy = (params: SuggestedParams, from: string, fee: number, assetIndex: number) => { - params.fee = fee - params.flatFee = true - return algosdk.makeAssetDestroyTxnWithSuggestedParamsFromObject({ - suggestedParams: params, - from, - assetIndex, + const acfgDestroy = (sender: string, fee: AlgoAmount, assetId: bigint) => { + return localnet.algorand.createTransaction.assetDestroy({ + sender, + assetId, + staticFee: fee, }) } - const pay = (params: SuggestedParams, amount: number, from: string, to: string, fee: number, closeRemainderTo?: string) => { - params.fee = fee - params.flatFee = true - return algosdk.makePaymentTxnWithSuggestedParamsFromObject({ - suggestedParams: params, + const pay = (amount: AlgoAmount, sender: string, receiver: string, fee: AlgoAmount, closeRemainderTo?: string) => { + return localnet.algorand.createTransaction.payment({ amount, - from, - to, + sender, + receiver, closeRemainderTo, + staticFee: fee, }) } const axfer = ( - params: SuggestedParams, - assetId: number | bigint, - amount: number | bigint, - from: string, - to: string, - revocationTarget?: string, - closeRemainderTo?: string, + assetId: bigint, + amount: bigint, + sender: string, + receiver: string, + fee: AlgoAmount, + clawbackTarget?: string, + closeAssetTo?: string, ) => { - return algosdk.makeAssetTransferTxnWithSuggestedParamsFromObject({ - suggestedParams: params, + return localnet.algorand.createTransaction.assetTransfer({ amount, - from, - to, - closeRemainderTo, - assetIndex: Number(assetId), - revocationTarget, + sender, + receiver, + closeAssetTo, + assetId, + clawbackTarget, + staticFee: fee, }) } test('Works for asset create transactions', async () => { // Assets are always minted into the creator/sender account, even if a reserve address is supplied - const { testAccount, algod } = localnet.context - const params = await algokit.getTransactionParams(undefined, algod) - const txns = await algokit.sendGroupOfTransactions( - { - transactions: [ - { - signer: testAccount, - transaction: acfgCreate(params, testAccount.addr, 2000, 100_000_000), - }, - ], - }, - algod, - ) + const { testAccount } = localnet.context + const txns = await localnet.algorand + .newGroup() + .addTransaction(await acfgCreate(testAccount.addr, microAlgo(2000), 100_000_000n)) + .send() const asset = txns.confirmations![0].assetIndex! const subscription = await subscribeAndVerify( @@ -120,32 +106,17 @@ describe('Subscribing to calls that effect balance changes', () => { }) test('Works for asset destroy transactions', async () => { - const { testAccount, algod } = localnet.context - const params = await algokit.getTransactionParams(undefined, algod) - const createAssetTxns = await algokit.sendGroupOfTransactions( - { - transactions: [ - { - signer: testAccount, - transaction: acfgCreate(params, testAccount.addr, 2000, 100_000_000), - }, - ], - }, - algod, - ) - const asset = createAssetTxns.confirmations![0].assetIndex! - - const txns = await algokit.sendGroupOfTransactions( - { - transactions: [ - { - signer: testAccount, - transaction: acfgDestroy(params, testAccount.addr, 2000, Number(asset)), - }, - ], - }, - algod, - ) + const { testAccount } = localnet.context + const createAssetTxns = await localnet.algorand + .newGroup() + .addTransaction(await acfgCreate(testAccount.addr, microAlgo(2000), 100_000_000n)) + .send() + const asset = BigInt(createAssetTxns.confirmations![0].assetIndex!) + + const txns = await localnet.algorand + .newGroup() + .addTransaction(await acfgDestroy(testAccount.addr, microAlgo(2000), asset)) + .send() const subscription = await subscribeAndVerify( { @@ -170,46 +141,28 @@ describe('Subscribing to calls that effect balance changes', () => { expect(transaction.balanceChanges[1].address).toBe(testAccount.addr) expect(transaction.balanceChanges[1].amount).toBe(0n) expect(transaction.balanceChanges[1].roles).toEqual([BalanceChangeRole.AssetDestroyer]) - expect(transaction.balanceChanges[1].assetId).toBe(asset) + expect(transaction.balanceChanges[1].assetId).toBe(Number(asset)) }) test('Works for > 53-bit totals', async () => { - const { testAccount, algod, generateAccount } = localnet.context - const params = await algokit.getTransactionParams(undefined, algod) + const { testAccount, generateAccount } = localnet.context const random = await generateAccount({ initialFunds: (1).algos() }) - const txns = await algokit.sendGroupOfTransactions( - { - transactions: [ - { - signer: testAccount, - transaction: acfgCreate(params, testAccount.addr, 2000, 135_640_597_783_270_612n), // this is > Number.MAX_SAFE_INTEGER - }, - ], - }, - algod, - ) - const asset = txns.confirmations![0].assetIndex! - const axferTxns = await algokit.sendGroupOfTransactions( - { - transactions: [ - { - signer: random, - transaction: axfer(params, asset, 0, random.addr, random.addr), // Opt-in - }, - { - signer: testAccount, - transaction: axfer(params, asset, 134_640_597_783_270_612n, testAccount.addr, random.addr), // this is > Number.MAX_SAFE_INTEGER - }, - ], - }, - algod, - ) + const txns = await localnet.algorand + .newGroup() + .addTransaction(await acfgCreate(testAccount.addr, microAlgo(2000), 135_640_597_783_270_612n)) // this is > Number.MAX_SAFE_INTEGER + .send() + const asset = BigInt(txns.confirmations![0].assetIndex!) + const axferTxns = await localnet.algorand + .newGroup() + .addTransaction(await axfer(asset, 0n, random.addr, random.addr, microAlgo(2000))) // Opt-in + .addTransaction(await axfer(asset, 134_640_597_783_270_612n, testAccount.addr, random.addr, microAlgo(2000))) // this is > Number.MAX_SAFE_INTEGER + .send() const subscription = await subscribeAndVerifyFilter( { balanceChanges: [ { - assetId: [Number(asset)], + assetId: [asset], address: testAccount.addr, role: [BalanceChangeRole.Sender], minAbsoluteAmount: 134_640_597_783_270_612n, @@ -223,7 +176,7 @@ describe('Subscribing to calls that effect balance changes', () => { subscription.algod.subscribedTransactions[0].balanceChanges?.map((b) => ({ ...b, address: b.address === testAccount.addr ? 'testAccount' : b.address === random.addr ? 'random' : b.address, - assetId: b.assetId === 0 ? 0 : b.assetId === asset ? 'ASSET' : b.assetId, + assetId: b.assetId === 0 ? 0 : b.assetId === Number(asset) ? 'ASSET' : b.assetId, })), ).toMatchInlineSnapshot(` [ @@ -257,7 +210,7 @@ describe('Subscribing to calls that effect balance changes', () => { subscription.indexer.subscribedTransactions[0].balanceChanges?.map((b) => ({ ...b, address: b.address === testAccount.addr ? 'testAccount' : b.address === random.addr ? 'random' : b.address, - assetId: b.assetId === 0 ? 0 : b.assetId === asset ? 'ASSET' : b.assetId, + assetId: b.assetId === 0 ? 0 : b.assetId === Number(asset) ? 'ASSET' : b.assetId, })), ).toMatchInlineSnapshot(` [ @@ -290,32 +243,15 @@ describe('Subscribing to calls that effect balance changes', () => { }) test('Works with balance change filter on fee algos', async () => { - const { testAccount, algod, generateAccount } = localnet.context + const { testAccount, generateAccount } = localnet.context const randomAccount = await generateAccount({ initialFunds: (1).algos() }) - const params = await algokit.getTransactionParams(undefined, algod) - const txns = await algokit.sendGroupOfTransactions( - { - transactions: [ - { - signer: randomAccount, - transaction: acfgCreate(params, randomAccount.addr, 3000), - }, - { - signer: testAccount, - transaction: acfgCreate(params, testAccount.addr, 1000), - }, - { - signer: testAccount, - transaction: acfgCreate(params, testAccount.addr, 3000), - }, - { - signer: testAccount, - transaction: acfgCreate(params, testAccount.addr, 5000), - }, - ], - }, - algod, - ) + const txns = await localnet.algorand + .newGroup() + .addTransaction(await acfgCreate(randomAccount.addr, microAlgo(3000))) + .addTransaction(await acfgCreate(testAccount.addr, microAlgo(1000))) + .addTransaction(await acfgCreate(testAccount.addr, microAlgo(3000))) + .addTransaction(await acfgCreate(testAccount.addr, microAlgo(5000))) + .send() await subscribeAndVerifyFilter( { @@ -337,7 +273,7 @@ describe('Subscribing to calls that effect balance changes', () => { test('Works with various balance change filters on algo transfer', async () => { try { - const { algod, generateAccount } = localnet.context + const { generateAccount } = localnet.context const account = await generateAccount({ initialFunds: (200_000).microAlgos() }) const account2 = await generateAccount({ initialFunds: (200_000).microAlgos() }) const account3 = await generateAccount({ initialFunds: (200_000).microAlgos() }) @@ -346,33 +282,20 @@ describe('Subscribing to calls that effect balance changes', () => { [account2.addr]: 'account2', [account3.addr]: 'account3', } - const params = await algokit.getTransactionParams(undefined, algod) - const txns = await algokit.sendGroupOfTransactions( - { - transactions: [ - pay(params, 1000, account.addr, account2.addr, 1000), // 0: account -2000, account2 +1000 - pay(params, 1000, account2.addr, account.addr, 1000), // 1: account +1000, account2 -2000 - pay(params, 2000, account.addr, account2.addr, 1000), // 2: account -3000, account2 +2000 - pay(params, 2000, account2.addr, account.addr, 1000), // 3: account +2000, account2 -3000 - pay(params, 3000, account.addr, account2.addr, 1000), // 4: account -4000, account2 +3000 - pay(params, 3000, account2.addr, account.addr, 1000), // 5: account +3000, account2 -4000 - // account 197k, account2 197k, account3 200k - pay(params, 100_000, account.addr, account2.addr, 1000, account3.addr), // 6: account -197k, account2 +100k, account3 +96k - pay(params, 100_000, account2.addr, account.addr, 1000, account.addr), // 7: account +296k, account2 -297k - pay(params, 100_000, account3.addr, account2.addr, 2000, account.addr), // 8: account +194k, account2 +100k, account3 -296k - pay(params, 0, account.addr, account.addr, 0), // 9: account 0 (fee covered by previous) - ].map((transaction) => ({ - signer: - algosdk.encodeAddress(transaction.from.publicKey) === account.addr - ? account - : algosdk.encodeAddress(transaction.from.publicKey) === account2.addr - ? account2 - : account3, - transaction, - })), - }, - algod, - ) + const txns = await localnet.algorand + .newGroup() + .addTransaction(await pay(microAlgo(1000), account.addr, account2.addr, microAlgo(1000))) // 0: account -2000, account2 +1000 + .addTransaction(await pay(microAlgo(1000), account2.addr, account.addr, microAlgo(1000))) // 1: account +1000, account2 -2000 + .addTransaction(await pay(microAlgo(2000), account.addr, account2.addr, microAlgo(1000))) // 2: account -3000, account2 +2000 + .addTransaction(await pay(microAlgo(2000), account2.addr, account.addr, microAlgo(1000))) // 3: account +2000, account2 -3000 + .addTransaction(await pay(microAlgo(3000), account.addr, account2.addr, microAlgo(1000))) // 4: account -4000, account2 +3000 + .addTransaction(await pay(microAlgo(3000), account2.addr, account.addr, microAlgo(1000))) // 5: account +3000, account2 -4000 + // account 197k, account2 197k, account3 200k + .addTransaction(await pay(microAlgo(100_000), account.addr, account2.addr, microAlgo(1000), account3.addr)) // 6: account -197k, account2 +100k, account3 +96k + .addTransaction(await pay(microAlgo(100_000), account2.addr, account.addr, microAlgo(1000), account.addr)) // 7: account +296k, account2 -297k + .addTransaction(await pay(microAlgo(100_000), account3.addr, account2.addr, microAlgo(2000), account.addr)) // 8: account +194k, account2 +100k, account3 -296k + .addTransaction(await pay(microAlgo(0), account.addr, account.addr, microAlgo(0))) // 9: account 0 (fee covered by previous) + .send() await subscribeAndVerifyFilter( { @@ -625,32 +548,27 @@ describe('Subscribing to calls that effect balance changes', () => { test('Works with various balance change filters on asset transfer', async () => { try { - const { algod, generateAccount, testAccount } = localnet.context + const { algorand, generateAccount, testAccount } = localnet.context const account = await generateAccount({ initialFunds: (1).algos() }) const account2 = await generateAccount({ initialFunds: (1).algos() }) const account3 = await generateAccount({ initialFunds: (1).algos() }) - const params = await algokit.getTransactionParams(undefined, algod) - const asset1 = Number( + + const asset1 = BigInt( ( - await algokit.sendTransaction( - { - transaction: acfgCreate(params, testAccount.addr, 1000), - from: testAccount, - }, - algod, - ) - ).confirmation!.assetIndex!, + await algorand + .newGroup() + .addTransaction(await acfgCreate(testAccount.addr, microAlgo(1000))) + .send() + ).confirmations![0].assetIndex!, ) - const asset2 = Number( + + const asset2 = BigInt( ( - await algokit.sendTransaction( - { - transaction: acfgCreate(params, testAccount.addr, 1001), - from: testAccount, - }, - algod, - ) - ).confirmation!.assetIndex!, + await algorand + .newGroup() + .addTransaction(await acfgCreate(testAccount.addr, microAlgo(1001))) + .send() + ).confirmations![0].assetIndex!, ) // eslint-disable-next-line no-console console.log('accounts', [testAccount.addr, account.addr, account2.addr, account3.addr], 'assets', [asset1, asset2]) @@ -661,52 +579,48 @@ describe('Subscribing to calls that effect balance changes', () => { [account3.addr]: 'account3', } const asset = { - [asset1]: 'asset1', - [asset2]: 'asset2', + [asset1.toString()]: 'asset1', + [asset2.toString()]: 'asset2', } - await algokit.assetOptIn({ account: account, assetId: asset1 }, algod) - await algokit.assetOptIn({ account: account2, assetId: asset1 }, algod) - await algokit.assetOptIn({ account: account3, assetId: asset1 }, algod) - await algokit.assetOptIn({ account: account, assetId: asset2 }, algod) - await algokit.assetOptIn({ account: account2, assetId: asset2 }, algod) - await algokit.assetOptIn({ account: account3, assetId: asset2 }, algod) - await algokit.transferAsset({ amount: 10, from: testAccount, to: account, assetId: asset1 }, algod) - await algokit.transferAsset({ amount: 10, from: testAccount, to: account2, assetId: asset1 }, algod) - await algokit.transferAsset({ amount: 20, from: testAccount, to: account3, assetId: asset1 }, algod) - await algokit.transferAsset({ amount: 10, from: testAccount, to: account, assetId: asset2 }, algod) - await algokit.transferAsset({ amount: 23, from: testAccount, to: account2, assetId: asset2 }, algod) + + await algorand.send.assetOptIn({ sender: account.addr, assetId: asset1 }) + await algorand.send.assetOptIn({ sender: account2.addr, assetId: asset1 }) + await algorand.send.assetOptIn({ sender: account3.addr, assetId: asset1 }) + await algorand.send.assetOptIn({ sender: account.addr, assetId: asset2 }) + await algorand.send.assetOptIn({ sender: account2.addr, assetId: asset2 }) + await algorand.send.assetOptIn({ sender: account3.addr, assetId: asset2 }) + await algorand.send.assetTransfer({ amount: 10n, sender: testAccount.addr, receiver: account.addr, assetId: asset1 }) + await algorand.send.assetTransfer({ amount: 10n, sender: testAccount.addr, receiver: account2.addr, assetId: asset1 }) + await algorand.send.assetTransfer({ amount: 20n, sender: testAccount.addr, receiver: account3.addr, assetId: asset1 }) + await algorand.send.assetTransfer({ amount: 10n, sender: testAccount.addr, receiver: account.addr, assetId: asset2 }) + await algorand.send.assetTransfer({ amount: 23n, sender: testAccount.addr, receiver: account2.addr, assetId: asset2 }) + // a1: account 10, account2 10, account3 0 // a2: account 10, account2 10, account3 0 - const txns = await algokit.sendGroupOfTransactions( - { - transactions: [ - axfer(params, asset1, 1, account.addr, account2.addr), // 0: a1: account -1, account2 +1 - axfer(params, asset1, 1, account2.addr, account.addr), // 1: a1: account +1, account2 -1 - axfer(params, asset1, 2, account.addr, account2.addr), // 2: a1: account -2, account2 +2 - axfer(params, asset1, 2, account2.addr, account.addr), // 3: a1: account +2, account2 -2 - axfer(params, asset1, 3, testAccount.addr, account2.addr, account.addr), // 4: a1: account -3, account2 +3 (clawback) - axfer(params, asset1, 3, testAccount.addr, account.addr, account2.addr), // 5: a1: account +3, account2 -3 (clawback) - axfer(params, asset1, 7, account.addr, account2.addr, undefined, account3.addr), // 6: a1: account -10, account2 +7, account3 +3 - (await algokit.assetOptIn({ account: account, assetId: asset1, skipSending: true }, algod)).transaction, // 7: Opt-in account to asset1 again - axfer(params, asset1, 7, account2.addr, account.addr, undefined, account.addr), // 8: a1: account +17, account2 -17 - (await algokit.assetOptIn({ account: account2, assetId: asset1, skipSending: true }, algod)).transaction, // 9: Opt-in account2 to asset1 again - axfer(params, asset1, 3, account3.addr, account2.addr, undefined, account.addr), // 10: a1: account +20, account2 +3, account3 -23 - axfer(params, asset2, 1, account.addr, account2.addr), // 11: a2: account -1, account2 +1 - axfer(params, asset2, 23, account2.addr, account.addr), // 12: a2: account +23, account2 -23 - ].map((transaction) => ({ - signer: - algosdk.encodeAddress(transaction.from.publicKey) === account.addr - ? account - : algosdk.encodeAddress(transaction.from.publicKey) === account2.addr - ? account2 - : algosdk.encodeAddress(transaction.from.publicKey) === testAccount.addr - ? testAccount - : account3, - transaction, - })), - }, - algod, - ) + const txns = await algorand + .newGroup() + .addTransaction(await axfer(asset1, 1n, account.addr, account2.addr, microAlgo(2000))) // 0: a1: account -1, account2 +1 + .addTransaction(await axfer(asset1, 1n, account2.addr, account.addr, microAlgo(2000))) // 1: a1: account +1, account2 -1 + .addTransaction(await axfer(asset1, 2n, account.addr, account2.addr, microAlgo(2000))) // 2: a1: account -2, account2 +2 + .addTransaction(await axfer(asset1, 2n, account2.addr, account.addr, microAlgo(2000))) // 3: a1: account +2, account2 -2 + .addTransaction(await axfer(asset1, 3n, testAccount.addr, account2.addr, microAlgo(2000), account.addr)) // 4: a1: account -3, account2 +3 (clawback) + .addTransaction(await axfer(asset1, 3n, testAccount.addr, account.addr, microAlgo(2000), account2.addr)) // 5: a1: account +3, account2 -3 (clawback) + .addTransaction(await axfer(asset1, 7n, account.addr, account2.addr, microAlgo(2000), undefined, account3.addr)) // 6: a1: account -10, account2 +7, account3 +3 + .addAssetOptIn({ + // 7: Opt-in account to asset1 again + sender: account.addr, + assetId: asset1, + }) + .addTransaction(await axfer(asset1, 7n, account2.addr, account.addr, microAlgo(2000), undefined, account.addr)) // 8: a1: account +17, account2 -17 + .addAssetOptIn({ + // 9: Opt-in account2 to asset1 again + sender: account2.addr, + assetId: asset1, + }) + .addTransaction(await axfer(asset1, 3n, account3.addr, account2.addr, microAlgo(2000), undefined, account.addr)) // 10: a1: account +20, account2 +3, account3 -23 + .addTransaction(await axfer(asset2, 1n, account.addr, account2.addr, microAlgo(2000))) // 11: a2: account -1, account2 +1 + .addTransaction(await axfer(asset2, 23n, account2.addr, account.addr, microAlgo(2000))) // 12: a2: account +23, account2 -23 + .send() await subscribeAndVerifyFilter( { @@ -895,7 +809,7 @@ describe('Subscribing to calls that effect balance changes', () => { .map((b) => ({ ...b, address: address[b.address], - assetId: asset[b.assetId], + assetId: asset[b.assetId.toString()], })) .sort((a, b) => a.address.localeCompare(b.address)) .map((b) => `${b.address}: ${Number(b.amount)} x ${b.assetId} (${b.roles.join(', ')})`), diff --git a/tests/scenarios/catchup-with-indexer.spec.ts b/tests/scenarios/catchup-with-indexer.spec.ts index a12ca43..8069c02 100644 --- a/tests/scenarios/catchup-with-indexer.spec.ts +++ b/tests/scenarios/catchup-with-indexer.spec.ts @@ -1,32 +1,25 @@ -import * as algokit from '@algorandfoundation/algokit-utils' import { algorandFixture } from '@algorandfoundation/algokit-utils/testing' import { afterEach, beforeEach, describe, expect, test, vitest } from 'vitest' import { GetSubscribedTransactionsFromSender, SendXTransactions } from '../transactions' describe('Subscribing using catchup-with-indexer', () => { - const localnet = algorandFixture(undefined, { - algodConfig: algokit.getDefaultLocalNetConfig('algod'), - indexerConfig: algokit.getDefaultLocalNetConfig('indexer'), - kmdConfig: algokit.getDefaultLocalNetConfig('kmd'), - }) - + const localnet = algorandFixture() beforeEach(localnet.beforeEach, 10e6) afterEach(() => { vitest.clearAllMocks() }) test('Processes start of chain to now when starting from beginning of chain', async () => { - const { algod, indexer, testAccount, generateAccount, waitForIndexerTransaction } = localnet.context + const { algorand, testAccount, generateAccount, waitForIndexerTransaction } = localnet.context // Ensure that if we are at round 0 there is a different transaction that won't be synced - await SendXTransactions(1, await generateAccount({ initialFunds: (3).algos() }), algod) - const { lastTxnRound, txns } = await SendXTransactions(1, testAccount, algod) + await SendXTransactions(1, await generateAccount({ initialFunds: (3).algos() }), algorand) + const { lastTxnRound, txns } = await SendXTransactions(1, testAccount, algorand) await waitForIndexerTransaction(txns[0].transaction.txID()) const subscribed = await GetSubscribedTransactionsFromSender( { roundsToSync: 1, syncBehaviour: 'catchup-with-indexer', watermark: 0, currentRound: lastTxnRound }, testAccount, - algod, - indexer, + algorand, ) expect(subscribed.currentRound).toBe(lastTxnRound) @@ -38,12 +31,12 @@ describe('Subscribing using catchup-with-indexer', () => { }) test('Limits the number of synced transactions to maxIndexerRoundsToSync', async () => { - const { algod, indexer, testAccount, generateAccount, waitForIndexerTransaction } = localnet.context + const { algorand, testAccount, generateAccount, waitForIndexerTransaction } = localnet.context // Ensure that if we are at round 0 there is a different transaction that won't be synced const randomAccount = await generateAccount({ initialFunds: (3).algos() }) - const { lastTxnRound: initialWatermark } = await SendXTransactions(1, randomAccount, algod) - const { txns } = await SendXTransactions(5, testAccount, algod) - const { lastTxnRound, txIds } = await SendXTransactions(1, randomAccount, algod) + const { lastTxnRound: initialWatermark } = await SendXTransactions(1, randomAccount, algorand) + const { txns } = await SendXTransactions(5, testAccount, algorand) + const { lastTxnRound, txIds } = await SendXTransactions(1, randomAccount, algorand) await waitForIndexerTransaction(txIds[0]) const expectedNewWatermark = Number(txns[2].confirmation!.confirmedRound!) - 1 const indexerRoundsToSync = expectedNewWatermark - initialWatermark @@ -57,8 +50,7 @@ describe('Subscribing using catchup-with-indexer', () => { currentRound: lastTxnRound, }, testAccount, - algod, - indexer, + algorand, ) expect(subscribed.currentRound).toBe(lastTxnRound) @@ -72,16 +64,15 @@ describe('Subscribing using catchup-with-indexer', () => { // Same behaviour as sync-oldest test('Processes all transactions after watermark when starting from an earlier round with other transactions', async () => { - const { algod, indexer, testAccount, waitForIndexerTransaction } = localnet.context - const { txns, lastTxnRound: olderTxnRound } = await SendXTransactions(2, testAccount, algod) - const { lastTxnRound: currentRound, txns: lastTxns } = await SendXTransactions(1, testAccount, algod) + const { algorand, testAccount, waitForIndexerTransaction } = localnet.context + const { txns, lastTxnRound: olderTxnRound } = await SendXTransactions(2, testAccount, algorand) + const { lastTxnRound: currentRound, txns: lastTxns } = await SendXTransactions(1, testAccount, algorand) await waitForIndexerTransaction(lastTxns[0].transaction.txID()) const subscribed = await GetSubscribedTransactionsFromSender( { roundsToSync: 1, syncBehaviour: 'catchup-with-indexer', watermark: olderTxnRound - 1, currentRound }, testAccount, - algod, - indexer, + algorand, ) expect(subscribed.currentRound).toBe(currentRound) @@ -94,15 +85,14 @@ describe('Subscribing using catchup-with-indexer', () => { }) test('Process multiple historic transactions using indexer and blends them in with algod transaction', async () => { - const { algod, indexer, testAccount, waitForIndexerTransaction } = localnet.context - const { txns, txIds, lastTxnRound } = await SendXTransactions(3, testAccount, algod) + const { algorand, testAccount, waitForIndexerTransaction } = localnet.context + const { txns, txIds, lastTxnRound } = await SendXTransactions(3, testAccount, algorand) await waitForIndexerTransaction(txIds[2]) const subscribed = await GetSubscribedTransactionsFromSender( { roundsToSync: 1, syncBehaviour: 'catchup-with-indexer', watermark: 0, currentRound: lastTxnRound }, testAccount, - algod, - indexer, + algorand, ) expect(subscribed.currentRound).toBe(lastTxnRound) diff --git a/tests/scenarios/events.spec.ts b/tests/scenarios/events.spec.ts index 830347b..9e1c95a 100644 --- a/tests/scenarios/events.spec.ts +++ b/tests/scenarios/events.spec.ts @@ -1,10 +1,8 @@ -import { sendGroupOfTransactions, transferAlgos } from '@algorandfoundation/algokit-utils' -import { Account } from 'algosdk' import invariant from 'tiny-invariant' import { afterEach, beforeAll, beforeEach, describe, expect, test } from 'vitest' import { Arc28Event } from '../../src/types' -import { TestingAppClient } from '../contract/client' import { filterFixture } from '../filterFixture' +import { app } from '../testing-app' describe('Subscribing to app calls that emit events', () => { const { @@ -51,37 +49,16 @@ describe('Subscribing to app calls that emit events', () => { ], } - const app = async (config: { create: boolean }, creator?: Account) => { - const app = new TestingAppClient( - { - resolveBy: 'id', - id: 0, - }, - localnet.context.algod, - ) - const creation = await app.create.bare({ - sender: creator ?? systemAccount(), - sendParams: { - skipSending: !config.create, - }, - }) - - return { - app, - creation, - } - } - test('Works for simple event', async () => { const { testAccount } = localnet.context - const app1 = await app({ create: true }) - const txn = await app1.app.emitSwapped({ a: 1, b: 2 }, { sender: testAccount }) + const app1 = await app({ create: true, algorand: localnet.algorand, creator: systemAccount() }) + const txn = await app1.appClient.send.emitSwapped({ args: { a: 1, b: 2 }, sender: testAccount.addr }) const subscription = ( await subscribeAndVerify( { sender: testAccount.addr, - appId: Number(app1.creation.appId), + appId: Number(app1.result.appId), }, txn, [ @@ -107,14 +84,14 @@ describe('Subscribing to app calls that emit events', () => { test('Processes multiple events', async () => { const { testAccount } = localnet.context - const app1 = await app({ create: true }) - const txn = await app1.app.emitSwappedTwice({ a: 1, b: 2 }, { sender: testAccount }) + const app1 = await app({ create: true, algorand: localnet.algorand, creator: systemAccount() }) + const txn = await app1.appClient.send.emitSwappedTwice({ args: { a: 1, b: 2 }, sender: testAccount.addr }) const subscription = ( await subscribeAndVerify( { sender: testAccount.addr, - appId: Number(app1.creation.appId), + appId: Number(app1.result.appId), }, txn, [ @@ -134,21 +111,21 @@ describe('Subscribing to app calls that emit events', () => { test('Respects app ID filter inclusion', async () => { const { testAccount } = localnet.context - const app1 = await app({ create: true }) - const txn = await app1.app.emitSwapped({ a: 1, b: 2 }, { sender: testAccount }) + const app1 = await app({ create: true, algorand: localnet.algorand, creator: systemAccount() }) + const txn = await app1.appClient.send.emitSwapped({ args: { a: 1, b: 2 }, sender: testAccount.addr }) const subscription = ( await subscribeAndVerify( { sender: testAccount.addr, - appId: Number(app1.creation.appId), + appId: Number(app1.result.appId), }, txn, [ { groupName: 'group1', events: [swappedEvent], - processForAppIds: [Number(app1.creation.appId)], + processForAppIds: [Number(app1.result.appId)], }, ], ) @@ -160,21 +137,21 @@ describe('Subscribing to app calls that emit events', () => { test('Respects app ID filter exclusion', async () => { const { testAccount } = localnet.context - const app1 = await app({ create: true }) - const txn = await app1.app.emitSwapped({ a: 1, b: 2 }, { sender: testAccount }) + const app1 = await app({ create: true, algorand: localnet.algorand, creator: systemAccount() }) + const txn = await app1.appClient.send.emitSwapped({ args: { a: 1, b: 2 }, sender: testAccount.addr }) const subscription = ( await subscribeAndVerify( { sender: testAccount.addr, - appId: Number(app1.creation.appId), + appId: Number(app1.result.appId), }, txn, [ { groupName: 'group1', events: [swappedEvent], - processForAppIds: [Number(app1.creation.appId) + 1], + processForAppIds: [Number(app1.result.appId) + 1], }, ], ) @@ -185,14 +162,14 @@ describe('Subscribing to app calls that emit events', () => { test('Respects app predicate filter inclusion', async () => { const { testAccount } = localnet.context - const app1 = await app({ create: true }) - const txn = await app1.app.emitSwapped({ a: 1, b: 2 }, { sender: testAccount }) + const app1 = await app({ create: true, algorand: localnet.algorand, creator: systemAccount() }) + const txn = await app1.appClient.send.emitSwapped({ args: { a: 1, b: 2 }, sender: testAccount.addr }) const subscription = ( await subscribeAndVerify( { sender: testAccount.addr, - appId: Number(app1.creation.appId), + appId: Number(app1.result.appId), }, txn, [ @@ -211,14 +188,14 @@ describe('Subscribing to app calls that emit events', () => { test('Respects app predicate filter exclusion', async () => { const { testAccount } = localnet.context - const app1 = await app({ create: true }) - const txn = await app1.app.emitSwapped({ a: 1, b: 2 }, { sender: testAccount }) + const app1 = await app({ create: true, algorand: localnet.algorand, creator: systemAccount() }) + const txn = await app1.appClient.send.emitSwapped({ args: { a: 1, b: 2 }, sender: testAccount.addr }) const subscription = ( await subscribeAndVerify( { sender: testAccount.addr, - appId: Number(app1.creation.appId), + appId: Number(app1.result.appId), }, txn, [ @@ -236,14 +213,14 @@ describe('Subscribing to app calls that emit events', () => { test('Works for complex event / multiple events in group', async () => { const { testAccount } = localnet.context - const app1 = await app({ create: true }) - const txn = await app1.app.emitComplex({ a: 1, b: 2, array: [1, 2, 3] }, { sender: testAccount }) + const app1 = await app({ create: true, algorand: localnet.algorand, creator: systemAccount() }) + const txn = await app1.appClient.send.emitComplex({ args: { a: 1, b: 2, array: [1, 2, 3] }, sender: testAccount.addr }) const subscription = ( await subscribeAndVerify( { sender: testAccount.addr, - appId: Number(app1.creation.appId), + appId: Number(app1.result.appId), }, txn, [ @@ -279,14 +256,14 @@ describe('Subscribing to app calls that emit events', () => { test('Works for multiple groups', async () => { const { testAccount } = localnet.context - const app1 = await app({ create: true }) - const txn = await app1.app.emitComplex({ a: 1, b: 2, array: [1, 2, 3] }, { sender: testAccount }) + const app1 = await app({ create: true, algorand: localnet.algorand, creator: systemAccount() }) + const txn = await app1.appClient.send.emitComplex({ args: { a: 1, b: 2, array: [1, 2, 3] }, sender: testAccount.addr }) const subscription = ( await subscribeAndVerify( { sender: testAccount.addr, - appId: Number(app1.creation.appId), + appId: Number(app1.result.appId), }, txn, [ @@ -313,19 +290,18 @@ describe('Subscribing to app calls that emit events', () => { }) test('Allows ARC-28 event subscription', async () => { - const { testAccount, algod } = localnet.context - const app1 = await app({ create: true }) - const txns = await sendGroupOfTransactions( - { - transactions: [ - app1.app.callAbi({ value: '1' }, { sender: testAccount, sendParams: { skipSending: true } }), - app1.app.emitSwapped({ a: 1, b: 2 }, { sender: testAccount, sendParams: { skipSending: true } }), - transferAlgos({ amount: (1).microAlgos(), from: testAccount, to: testAccount.addr, skipSending: true }, algod), - ], - signer: testAccount, - }, - algod, - ) + const { testAccount } = localnet.context + const app1 = await app({ create: true, algorand: localnet.algorand, creator: systemAccount() }) + const txns = await localnet.algorand + .newGroup() + .addAppCallMethodCall(await app1.appClient.params.callAbi({ args: { value: '1' }, sender: testAccount.addr })) + .addAppCallMethodCall(await app1.appClient.params.emitSwapped({ args: { a: 1, b: 2 }, sender: testAccount.addr })) + .addPayment({ + amount: (1).microAlgos(), + sender: testAccount.addr, + receiver: testAccount.addr, + }) + .send() await subscribeAndVerifyFilter( { @@ -343,19 +319,14 @@ describe('Subscribing to app calls that emit events', () => { }) test('ARC-28 event subscription validates app ID (include)', async () => { - const { testAccount, algod } = localnet.context - const app1 = await app({ create: true }) - const txns = await sendGroupOfTransactions( - { - transactions: [ - app1.app.callAbi({ value: '1' }, { sender: testAccount, sendParams: { skipSending: true } }), - app1.app.emitSwapped({ a: 1, b: 2 }, { sender: testAccount, sendParams: { skipSending: true } }), - transferAlgos({ amount: (1).microAlgos(), from: testAccount, to: testAccount.addr, skipSending: true }, algod), - ], - signer: testAccount, - }, - algod, - ) + const { testAccount } = localnet.context + const app1 = await app({ create: true, algorand: localnet.algorand, creator: systemAccount() }) + const txns = await localnet.algorand + .newGroup() + .addAppCallMethodCall(await app1.appClient.params.callAbi({ args: { value: '1' }, sender: testAccount.addr })) + .addAppCallMethodCall(await app1.appClient.params.emitSwapped({ args: { a: 1, b: 2 }, sender: testAccount.addr })) + .addPayment({ amount: (1).microAlgos(), sender: testAccount.addr, receiver: testAccount.addr }) + .send() await subscribeAndVerifyFilter( { @@ -367,26 +338,21 @@ describe('Subscribing to app calls that emit events', () => { { groupName: 'group1', events: [swappedEvent], - processForAppIds: [Number(app1.creation.appId)], + processForAppIds: [Number(app1.result.appId)], }, ], ) }) test('ARC-28 event subscription validates app ID (exclude)', async () => { - const { testAccount, algod } = localnet.context - const app1 = await app({ create: true }) - const txns = await sendGroupOfTransactions( - { - transactions: [ - app1.app.callAbi({ value: '1' }, { sender: testAccount, sendParams: { skipSending: true } }), - app1.app.emitSwapped({ a: 1, b: 2 }, { sender: testAccount, sendParams: { skipSending: true } }), - transferAlgos({ amount: (1).microAlgos(), from: testAccount, to: testAccount.addr, skipSending: true }, algod), - ], - signer: testAccount, - }, - algod, - ) + const { testAccount } = localnet.context + const app1 = await app({ create: true, algorand: localnet.algorand, creator: systemAccount() }) + const txns = await localnet.algorand + .newGroup() + .addAppCallMethodCall(await app1.appClient.params.callAbi({ args: { value: '1' }, sender: testAccount.addr })) + .addAppCallMethodCall(await app1.appClient.params.emitSwapped({ args: { a: 1, b: 2 }, sender: testAccount.addr })) + .addPayment({ amount: (1).microAlgos(), sender: testAccount.addr, receiver: testAccount.addr }) + .send() const subscription = await subscribeAlgod( { @@ -398,7 +364,7 @@ describe('Subscribing to app calls that emit events', () => { { groupName: 'group1', events: [swappedEvent], - processForAppIds: [Number(app1.creation.appId) + 1], + processForAppIds: [Number(app1.result.appId) + 1], }, ], ) @@ -415,7 +381,7 @@ describe('Subscribing to app calls that emit events', () => { { groupName: 'group1', events: [swappedEvent], - processForAppIds: [Number(app1.creation.appId) + 1], + processForAppIds: [Number(app1.result.appId) + 1], }, ], ) @@ -424,19 +390,14 @@ describe('Subscribing to app calls that emit events', () => { }) test('ARC-28 event subscription validates predicate (include)', async () => { - const { testAccount, algod } = localnet.context - const app1 = await app({ create: true }) - const txns = await sendGroupOfTransactions( - { - transactions: [ - app1.app.callAbi({ value: '1' }, { sender: testAccount, sendParams: { skipSending: true } }), - app1.app.emitSwapped({ a: 1, b: 2 }, { sender: testAccount, sendParams: { skipSending: true } }), - transferAlgos({ amount: (1).microAlgos(), from: testAccount, to: testAccount.addr, skipSending: true }, algod), - ], - signer: testAccount, - }, - algod, - ) + const { testAccount } = localnet.context + const app1 = await app({ create: true, algorand: localnet.algorand, creator: systemAccount() }) + const txns = await localnet.algorand + .newGroup() + .addAppCallMethodCall(await app1.appClient.params.callAbi({ args: { value: '1' }, sender: testAccount.addr })) + .addAppCallMethodCall(await app1.appClient.params.emitSwapped({ args: { a: 1, b: 2 }, sender: testAccount.addr })) + .addPayment({ amount: (1).microAlgos(), sender: testAccount.addr, receiver: testAccount.addr }) + .send() await subscribeAndVerifyFilter( { @@ -455,19 +416,14 @@ describe('Subscribing to app calls that emit events', () => { }) test('ARC-28 event subscription validates predicate (exclude)', async () => { - const { testAccount, algod } = localnet.context - const app1 = await app({ create: true }) - const txns = await sendGroupOfTransactions( - { - transactions: [ - app1.app.callAbi({ value: '1' }, { sender: testAccount, sendParams: { skipSending: true } }), - app1.app.emitSwapped({ a: 1, b: 2 }, { sender: testAccount, sendParams: { skipSending: true } }), - transferAlgos({ amount: (1).microAlgos(), from: testAccount, to: testAccount.addr, skipSending: true }, algod), - ], - signer: testAccount, - }, - algod, - ) + const { testAccount } = localnet.context + const app1 = await app({ create: true, algorand: localnet.algorand, creator: systemAccount() }) + const txns = await localnet.algorand + .newGroup() + .addAppCallMethodCall(await app1.appClient.params.callAbi({ args: { value: '1' }, sender: testAccount.addr })) + .addAppCallMethodCall(await app1.appClient.params.emitSwapped({ args: { a: 1, b: 2 }, sender: testAccount.addr })) + .addPayment({ amount: (1).microAlgos(), sender: testAccount.addr, receiver: testAccount.addr }) + .send() const subscription = await subscribeAlgod( { @@ -505,19 +461,14 @@ describe('Subscribing to app calls that emit events', () => { }) test('ARC-28 event subscription validates group', async () => { - const { testAccount, algod } = localnet.context - const app1 = await app({ create: true }) - const txns = await sendGroupOfTransactions( - { - transactions: [ - app1.app.callAbi({ value: '1' }, { sender: testAccount, sendParams: { skipSending: true } }), - app1.app.emitSwapped({ a: 1, b: 2 }, { sender: testAccount, sendParams: { skipSending: true } }), - transferAlgos({ amount: (1).microAlgos(), from: testAccount, to: testAccount.addr, skipSending: true }, algod), - ], - signer: testAccount, - }, - algod, - ) + const { testAccount } = localnet.context + const app1 = await app({ create: true, algorand: localnet.algorand, creator: systemAccount() }) + const txns = await localnet.algorand + .newGroup() + .addAppCallMethodCall(await app1.appClient.params.callAbi({ args: { value: '1' }, sender: testAccount.addr })) + .addAppCallMethodCall(await app1.appClient.params.emitSwapped({ args: { a: 1, b: 2 }, sender: testAccount.addr })) + .addPayment({ amount: (1).microAlgos(), sender: testAccount.addr, receiver: testAccount.addr }) + .send() const subscription = await subscribeAlgod( { diff --git a/tests/scenarios/fail.spec.ts b/tests/scenarios/fail.spec.ts index edf467b..e5e925b 100644 --- a/tests/scenarios/fail.spec.ts +++ b/tests/scenarios/fail.spec.ts @@ -11,27 +11,27 @@ describe('Subscribing using fail', () => { }) test('Fails if too far from the tip of the chain', async () => { - const { algod, testAccount } = localnet.context - const { lastTxnRound } = await SendXTransactions(2, testAccount, algod) + const { algorand, testAccount } = localnet.context + const { lastTxnRound } = await SendXTransactions(2, testAccount, algorand) await expect( async () => await GetSubscribedTransactionsFromSender( { roundsToSync: 1, syncBehaviour: 'fail', watermark: 0, currentRound: lastTxnRound }, testAccount, - algod, + algorand, ), ).rejects.toThrow(`Invalid round number to subscribe from 1; current round number is ${lastTxnRound}`) }) test("Doesn't fail if not too far from the tip of the chain", async () => { - const { algod, testAccount } = localnet.context - const { txns, lastTxnRound } = await SendXTransactions(2, testAccount, algod) + const { algorand, testAccount } = localnet.context + const { txns, lastTxnRound } = await SendXTransactions(2, testAccount, algorand) const subscribed = await GetSubscribedTransactionsFromSender( { roundsToSync: 1, syncBehaviour: 'fail', watermark: lastTxnRound - 1, currentRound: lastTxnRound }, testAccount, - algod, + algorand, ) expect(subscribed.currentRound).toBe(lastTxnRound) diff --git a/tests/scenarios/filters.spec.ts b/tests/scenarios/filters.spec.ts index d080e7a..f9f91bd 100644 --- a/tests/scenarios/filters.spec.ts +++ b/tests/scenarios/filters.spec.ts @@ -1,10 +1,10 @@ -import * as algokit from '@algorandfoundation/algokit-utils' import { ApplicationOnComplete } from '@algorandfoundation/algokit-utils/types/indexer' import { SendAtomicTransactionComposerResults } from '@algorandfoundation/algokit-utils/types/transaction' -import algosdk, { Account, TransactionType } from 'algosdk' +import { Account, TransactionType } from 'algosdk' import { afterEach, beforeAll, beforeEach, describe, test } from 'vitest' -import { TestingAppClient } from '../contract/client' +import { TestingAppFactory } from '../contract/client' import { filterFixture } from '../filterFixture' +import { app } from '../testing-app' describe('Subscribing using various filters', () => { const { localnet, systemAccount, subscribeAndVerifyFilter, extractFromGroupResult, ...hooks } = filterFixture() @@ -18,49 +18,23 @@ describe('Subscribing using various filters', () => { afterEach(hooks.afterEach) const createAsset = async (creator?: Account) => { - const create = await algokit.sendTransaction( - { - from: creator ?? systemAccount(), - transaction: await createAssetTxn(creator ?? systemAccount()), - }, - localnet.context.algod, - ) + const create = await localnet.algorand + .newGroup() + .addTransaction(await createAssetTxn(creator ?? systemAccount())) + .send() return { - assetId: Number(create.confirmation!.assetIndex!), + assetId: BigInt(create.confirmations[0].assetIndex!), ...create, } } const createAssetTxn = async (creator: Account) => { - return algosdk.makeAssetCreateTxnWithSuggestedParamsFromObject({ - from: creator ? creator.addr : systemAccount().addr, + return await localnet.algorand.createTransaction.assetCreate({ + sender: creator ? creator.addr : systemAccount().addr, decimals: 0, - total: 100, - defaultFrozen: false, - suggestedParams: await algokit.getTransactionParams(undefined, localnet.context.algod), - }) - } - - const app = async (config: { create: boolean }, creator?: Account) => { - const app = new TestingAppClient( - { - resolveBy: 'id', - id: 0, - }, - localnet.context.algod, - ) - const creation = await app.create.bare({ - sender: creator ?? systemAccount(), - sendParams: { - skipSending: !config.create, - }, + total: 100n, }) - - return { - app, - creation, - } } let algoTransfersData: @@ -72,23 +46,31 @@ describe('Subscribing using various filters', () => { } | undefined = undefined const algoTransfersFixture = async () => { - const { algod, generateAccount } = localnet.context + const { generateAccount } = localnet.context const testAccount = await generateAccount({ initialFunds: (10).algos() }) const account2 = await generateAccount({ initialFunds: (3).algos() }) - const account3 = algokit.randomAccount() - const txns = await algokit.sendGroupOfTransactions( - { - transactions: [ - await algokit.transferAlgos({ amount: (1).algos(), from: testAccount, to: account2, note: 'a', skipSending: true }, algod), - await algokit.transferAlgos({ amount: (2).algos(), from: testAccount, to: account3, note: 'b', skipSending: true }, algod), - await algokit.transferAlgos({ amount: (1).algos(), from: account2, to: testAccount, note: 'c', skipSending: true }, algod), - ].map((t) => ({ - transaction: t.transaction, - signer: algosdk.encodeAddress(t.transaction.from.publicKey) === testAccount.addr ? testAccount : account2, - })), - }, - algod, - ) + const account3 = localnet.algorand.account.random().account + const txns = await localnet.algorand + .newGroup() + .addPayment({ + sender: testAccount.addr, + receiver: account2.addr, + amount: (1).algos(), + note: 'a', + }) + .addPayment({ + sender: testAccount.addr, + receiver: account3.addr, + amount: (2).algos(), + note: 'b', + }) + .addPayment({ + sender: account2.addr, + receiver: testAccount.addr, + amount: (1).algos(), + note: 'c', + }) + .send() algoTransfersData = { testAccount, @@ -147,7 +129,7 @@ describe('Subscribing using various filters', () => { await subscribeAndVerifyFilter( { sender: testAccount.addr, - minAmount: (1).algos().microAlgos + 1, + minAmount: (1).algos().microAlgos + 1n, }, extractFromGroupResult(txns, 1), ) @@ -159,7 +141,7 @@ describe('Subscribing using various filters', () => { await subscribeAndVerifyFilter( { sender: testAccount.addr, - maxAmount: (1).algos().microAlgos + 1, + maxAmount: (1).algos().microAlgos + 1n, }, extractFromGroupResult(txns, 0), ) @@ -195,23 +177,34 @@ describe('Subscribing using various filters', () => { } | undefined = undefined const assetsFixture = async () => { - const { algod, generateAccount } = localnet.context + const { generateAccount } = localnet.context const testAccount = await generateAccount({ initialFunds: (10).algos() }) const asset1 = await createAsset(testAccount) const asset2 = await createAsset() - const txns = await algokit.sendGroupOfTransactions( - { - transactions: [ - algokit.assetOptIn({ account: testAccount, assetId: asset1.assetId, skipSending: true }, algod), - algokit.assetOptIn({ account: testAccount, assetId: asset2.assetId, skipSending: true }, algod), - await createAssetTxn(testAccount), - algokit.transferAsset({ assetId: asset1.assetId, amount: 1, from: testAccount, to: testAccount, skipSending: true }, algod), - algokit.transferAsset({ assetId: asset1.assetId, amount: 2, from: testAccount, to: testAccount, skipSending: true }, algod), - ], - signer: testAccount, - }, - algod, - ) + const txns = await localnet.algorand.send + .newGroup() + .addAssetOptIn({ + sender: testAccount.addr, + assetId: asset1.assetId, + }) + .addAssetOptIn({ + sender: testAccount.addr, + assetId: asset2.assetId, + }) + .addTransaction(await createAssetTxn(testAccount)) + .addAssetTransfer({ + assetId: asset1.assetId, + amount: 1n, + sender: testAccount.addr, + receiver: testAccount.addr, + }) + .addAssetTransfer({ + assetId: asset1.assetId, + amount: 2n, + sender: testAccount.addr, + receiver: testAccount.addr, + }) + .send() assetsData = { asset1, @@ -360,29 +353,28 @@ describe('Subscribing using various filters', () => { let appData: | { - app1: Awaited> - app2: Awaited> + app1: Awaited> + app2: Awaited> testAccount: Account txns: SendAtomicTransactionComposerResults } | undefined = undefined const appsFixture = async () => { - const { algod, generateAccount } = localnet.context + const { generateAccount } = localnet.context const testAccount = await generateAccount({ initialFunds: (10).algos() }) - const app1 = await app({ create: true }) - const app2 = await app({ create: true }) - const txns = await algokit.sendGroupOfTransactions( - { - transactions: [ - app1.app.callAbi({ value: 'test1' }, { sender: testAccount, sendParams: { skipSending: true } }), - app2.app.callAbi({ value: 'test2' }, { sender: testAccount, sendParams: { skipSending: true } }), - (await app({ create: false }, testAccount)).creation.transaction, - app1.app.optIn.optIn({}, { sender: testAccount, sendParams: { skipSending: true } }), - ], - signer: testAccount, - }, - algod, - ) + + const temp = await app({ create: false, algorand: localnet.algorand, creator: testAccount }) + await localnet.algorand.send.newGroup().addTransaction(temp).send() + + const app1 = await app({ create: true, algorand: localnet.algorand, creator: systemAccount(), note: 'app1' }) + const app2 = await app({ create: true, algorand: localnet.algorand, creator: systemAccount(), note: 'app2' }) + const txns = await localnet.algorand + .newGroup() + .addAppCallMethodCall(await app1.appClient.params.callAbi({ args: { value: 'test1' }, sender: testAccount.addr })) + .addAppCallMethodCall(await app2.appClient.params.callAbi({ args: { value: 'test2' }, sender: testAccount.addr })) + .addTransaction(await app({ create: false, algorand: localnet.algorand, creator: testAccount })) + .addAppCallMethodCall(await app1.appClient.params.optIn.optIn({ sender: testAccount.addr, args: {} })) + .send() appData = { app1, @@ -412,7 +404,7 @@ describe('Subscribing using various filters', () => { await subscribeAndVerifyFilter( { sender: testAccount.addr, - appId: Number(app1.creation.confirmation!.applicationIndex!), + appId: Number(app1.result.confirmation!.applicationIndex!), }, [extractFromGroupResult(txns, 0), extractFromGroupResult(txns, 3)], ) @@ -420,7 +412,7 @@ describe('Subscribing using various filters', () => { await subscribeAndVerifyFilter( { sender: testAccount.addr, - appId: [Number(app1.creation.confirmation!.applicationIndex!), Number(app2.creation.confirmation!.applicationIndex!)], + appId: [Number(app1.result.confirmation!.applicationIndex!), Number(app2.result.confirmation!.applicationIndex!)], }, [extractFromGroupResult(txns, 0), extractFromGroupResult(txns, 1), extractFromGroupResult(txns, 3)], ) diff --git a/tests/scenarios/inner_transactions.spec.ts b/tests/scenarios/inner_transactions.spec.ts index b70714e..1c180d4 100644 --- a/tests/scenarios/inner_transactions.spec.ts +++ b/tests/scenarios/inner_transactions.spec.ts @@ -1,10 +1,9 @@ -import * as algokit from '@algorandfoundation/algokit-utils' import { algorandFixture } from '@algorandfoundation/algokit-utils/testing' import { SendAtomicTransactionComposerResults, SendTransactionResult } from '@algorandfoundation/algokit-utils/types/transaction' -import algosdk, { Account, Transaction, TransactionType } from 'algosdk' +import { Account, Transaction, TransactionType } from 'algosdk' import { afterEach, beforeAll, beforeEach, describe, expect, test, vitest } from 'vitest' import { TransactionFilter } from '../../src/types' -import { TestingAppClient } from '../contract/client' +import { app } from '../testing-app' import { GetSubscribedTransactions, SendXTransactions } from '../transactions' describe('Inner transactions', () => { @@ -23,7 +22,7 @@ describe('Inner transactions', () => { const subscribeAndVerifyFilter = async (filter: TransactionFilter, ...result: (SendTransactionResult & { id: string })[]) => { // Ensure there is another transaction so algod subscription can process something - await SendXTransactions(1, systemAccount, localnet.context.algod) + await SendXTransactions(1, systemAccount, localnet.algorand) // Wait for indexer to catch up await localnet.context.waitForIndexer() // Run the subscription twice - once that will pick up using algod and once using indexer @@ -37,7 +36,7 @@ describe('Inner transactions', () => { currentRound: Number(result[result.length - 1].confirmation?.confirmedRound), filters: filter, }, - localnet.context.algod, + localnet.algorand, ), GetSubscribedTransactions( { @@ -47,8 +46,7 @@ describe('Inner transactions', () => { currentRound: Number(result[result.length - 1].confirmation?.confirmedRound) + 1, filters: filter, }, - localnet.context.algod, - localnet.context.indexer, + localnet.algorand, ), ]) @@ -81,85 +79,31 @@ describe('Inner transactions', () => { } } - const createAsset = async (creator?: Account) => { - const create = await algokit.sendTransaction( - { - from: creator ?? systemAccount, - transaction: await createAssetTxn(creator ?? systemAccount), - }, - localnet.context.algod, - ) - - return { - assetId: Number(create.confirmation!.assetIndex!), - ...create, - } - } - - const createAssetTxn = async (creator: Account) => { - return algosdk.makeAssetCreateTxnWithSuggestedParamsFromObject({ - from: creator ? creator.addr : systemAccount.addr, - decimals: 0, - total: 100, - defaultFrozen: false, - suggestedParams: await algokit.getTransactionParams(undefined, localnet.context.algod), - }) - } - - const app = async (config: { create: boolean }, creator?: Account) => { - const app = new TestingAppClient( - { - resolveBy: 'id', - id: 0, - }, - localnet.context.algod, - ) - const creation = await app.create.bare({ - sender: creator ?? systemAccount, - sendParams: { - skipSending: !config.create, - }, - }) + test('Is processed alongside normal transaction', async () => { + const { testAccount } = localnet.context + const app1 = await app({ create: true, algorand: localnet.algorand, creator: systemAccount }) - return { - app, - creation, - } - } + const txns = await localnet.algorand + .newGroup() + .addPayment({ + amount: (100_001).microAlgos(), + receiver: app1.appClient.appAddress, + sender: testAccount.addr, + }) + .addPayment({ + amount: (1).microAlgos(), + receiver: testAccount.addr, + sender: testAccount.addr, + }) + .addAppCallMethodCall( + await app1.appClient.params.issueTransferToSender({ + args: { amount: 1 }, + sender: testAccount.addr, + staticFee: (2000).microAlgos(), + }), + ) + .send() - test('Is processed alongside normal transaction', async () => { - const { testAccount, algod } = localnet.context - const app1 = await app({ create: true }) - const txns = await algokit.sendGroupOfTransactions( - { - transactions: [ - algokit.transferAlgos( - { - amount: (100_001).microAlgos(), - to: (await app1.app.appClient.getAppReference()).appAddress, - from: testAccount, - skipSending: true, - }, - algod, - ), - algokit.transferAlgos( - { - amount: (1).microAlgos(), - to: testAccount, - from: testAccount, - skipSending: true, - }, - algod, - ), - app1.app.issueTransferToSender( - { amount: 1 }, - { sender: testAccount, sendParams: { skipSending: true, fee: (2000).microAlgos() } }, - ), - ], - signer: testAccount, - }, - algod, - ) await subscribeAndVerifyFilter( { type: TransactionType.pay, diff --git a/tests/scenarios/multiple-filters.spec.ts b/tests/scenarios/multiple-filters.spec.ts index 4bdd372..b3b7c4d 100644 --- a/tests/scenarios/multiple-filters.spec.ts +++ b/tests/scenarios/multiple-filters.spec.ts @@ -10,29 +10,28 @@ describe('Subscribing using multiple filters', () => { vitest.clearAllMocks() }) - test('Process multiple historic transactions using indexer and blends them in with algod transaction', async () => { - const { algod, indexer, testAccount, waitForIndexerTransaction, generateAccount } = localnet.context + test('Process multiple historic transactions using indexer and blends them in with algorand transaction', async () => { + const { algorand, testAccount, waitForIndexerTransaction, generateAccount } = localnet.context const senders = [ await generateAccount({ initialFunds: (5).algos() }), await generateAccount({ initialFunds: (5).algos() }), await generateAccount({ initialFunds: (5).algos() }), ] // Indexer should pick these up - const { txIds: txIds1 } = await SendXTransactions(2, senders[0], algod) - const { txIds: txIds2 } = await SendXTransactions(2, senders[1], algod) - const { txIds: txIds3 } = await SendXTransactions(2, senders[2], algod) - const { lastTxnRound: postIndexerRound } = await SendXTransactions(1, testAccount, algod) - const { txIds: txIds11 } = await SendXTransactions(1, senders[0], algod) - const { txIds: txIds22 } = await SendXTransactions(1, senders[1], algod) - const { txIds: txIds33 } = await SendXTransactions(1, senders[2], algod) - const { txIds, lastTxnRound } = await SendXTransactions(1, testAccount, algod) + const { txIds: txIds1 } = await SendXTransactions(2, senders[0], algorand) + const { txIds: txIds2 } = await SendXTransactions(2, senders[1], algorand) + const { txIds: txIds3 } = await SendXTransactions(2, senders[2], algorand) + const { lastTxnRound: postIndexerRound } = await SendXTransactions(1, testAccount, algorand) + const { txIds: txIds11 } = await SendXTransactions(1, senders[0], algorand) + const { txIds: txIds22 } = await SendXTransactions(1, senders[1], algorand) + const { txIds: txIds33 } = await SendXTransactions(1, senders[2], algorand) + const { txIds, lastTxnRound } = await SendXTransactions(1, testAccount, algorand) await waitForIndexerTransaction(txIds[0]) const subscribed = await GetSubscribedTransactionsFromSender( { roundsToSync: lastTxnRound - postIndexerRound, syncBehaviour: 'catchup-with-indexer', watermark: 0, currentRound: lastTxnRound }, senders, - algod, - indexer, + algorand, ) expect(subscribed.currentRound).toBe(lastTxnRound) diff --git a/tests/scenarios/skip-sync-newest.spec.ts b/tests/scenarios/skip-sync-newest.spec.ts index b9dd6e8..1b1873f 100644 --- a/tests/scenarios/skip-sync-newest.spec.ts +++ b/tests/scenarios/skip-sync-newest.spec.ts @@ -11,13 +11,13 @@ describe('Subscribing using skip-sync-newest', () => { }) test('Only processes the latest transaction when starting from beginning of chain', async () => { - const { algod, testAccount } = localnet.context - const { txns, lastTxnRound } = await SendXTransactions(2, testAccount, algod) + const { algorand, testAccount } = localnet.context + const { txns, lastTxnRound } = await SendXTransactions(2, testAccount, algorand) const subscribed = await GetSubscribedTransactionsFromSender( { roundsToSync: 1, syncBehaviour: 'skip-sync-newest', watermark: 0, currentRound: lastTxnRound }, testAccount, - algod, + algorand, ) expect(subscribed.currentRound).toBe(lastTxnRound) @@ -29,14 +29,14 @@ describe('Subscribing using skip-sync-newest', () => { }) test('Only processes the latest transaction when starting from an earlier round with other transactions', async () => { - const { algod, testAccount } = localnet.context - const { lastTxnRound: olderTxnRound } = await SendXTransactions(2, testAccount, algod) - const { txns, lastTxnRound: currentRound } = await SendXTransactions(1, testAccount, algod) + const { algorand, testAccount } = localnet.context + const { lastTxnRound: olderTxnRound } = await SendXTransactions(2, testAccount, algorand) + const { txns, lastTxnRound: currentRound } = await SendXTransactions(1, testAccount, algorand) const subscribed = await GetSubscribedTransactionsFromSender( { roundsToSync: 1, syncBehaviour: 'skip-sync-newest', watermark: olderTxnRound - 1, currentRound }, testAccount, - algod, + algorand, ) expect(subscribed.currentRound).toBe(currentRound) @@ -48,13 +48,13 @@ describe('Subscribing using skip-sync-newest', () => { }) test('Process multiple transactions', async () => { - const { algod, testAccount } = localnet.context - const { txns, lastTxnRound, rounds } = await SendXTransactions(3, testAccount, algod) + const { algorand, testAccount } = localnet.context + const { txns, lastTxnRound, rounds } = await SendXTransactions(3, testAccount, algorand) const subscribed = await GetSubscribedTransactionsFromSender( { roundsToSync: lastTxnRound - rounds[1] + 1, syncBehaviour: 'skip-sync-newest', watermark: 0, currentRound: lastTxnRound }, testAccount, - algod, + algorand, ) expect(subscribed.currentRound).toBe(lastTxnRound) diff --git a/tests/scenarios/subscriber.spec.ts b/tests/scenarios/subscriber.spec.ts index e30ed48..e3fc0be 100644 --- a/tests/scenarios/subscriber.spec.ts +++ b/tests/scenarios/subscriber.spec.ts @@ -1,8 +1,7 @@ /* eslint-disable no-console */ -import * as algokit from '@algorandfoundation/algokit-utils' +import { AlgorandClient } from '@algorandfoundation/algokit-utils' import { algorandFixture } from '@algorandfoundation/algokit-utils/testing' -import { SendTransactionFrom } from '@algorandfoundation/algokit-utils/types/transaction' -import { Algodv2, Indexer } from 'algosdk' +import { Account } from 'algosdk' import { afterEach, beforeEach, describe, expect, test, vitest } from 'vitest' import { AlgorandSubscriber } from '../../src' import { AlgorandSubscriberConfig } from '../../src/types' @@ -19,9 +18,8 @@ describe('AlgorandSubscriber', () => { }) const getSubscriber = ( - config: { testAccount: SendTransactionFrom; configOverrides?: Partial; initialWatermark?: number }, - algod: Algodv2, - indexer?: Indexer, + config: { testAccount: Account; configOverrides?: Partial; initialWatermark?: number }, + algorand: AlgorandClient, ) => { let watermark = config.initialWatermark ?? 0 const subscribedTxns: string[] = [] @@ -33,7 +31,7 @@ describe('AlgorandSubscriber', () => { { name: 'test-txn', filter: { - sender: algokit.getSenderAddress(config.testAccount), + sender: config.testAccount.addr, }, }, ...(config.configOverrides?.filters ?? []), @@ -44,8 +42,8 @@ describe('AlgorandSubscriber', () => { (w) => (watermark = w), ), }, - algod, - indexer, + algorand.client.algod, + algorand.client.indexer, ) subscriber.on('test-txn', (r) => { subscribedTxns.push(r.id) @@ -58,13 +56,13 @@ describe('AlgorandSubscriber', () => { } test('Subscribes to transactions correctly when controlling polling', async () => { - const { algod, testAccount, generateAccount } = localnet.context - const { lastTxnRound, txIds } = await SendXTransactions(1, testAccount, algod) + const { algorand, testAccount, generateAccount } = localnet.context + const { lastTxnRound, txIds } = await SendXTransactions(1, testAccount, algorand) const { subscriber, subscribedTestAccountTxns: subscribedTxns, getWatermark, - } = getSubscriber({ testAccount, initialWatermark: lastTxnRound - 1 }, algod) + } = getSubscriber({ testAccount, initialWatermark: lastTxnRound - 1 }, algorand) // Initial catch up with indexer const result = await subscriber.pollOnce() @@ -79,13 +77,13 @@ describe('AlgorandSubscriber', () => { expect(result.subscribedTransactions.map((t) => t.id)).toEqual(txIds) // Random transaction - const { lastTxnRound: lastTxnRound2 } = await SendXTransactions(1, await generateAccount({ initialFunds: (3).algos() }), algod) + const { lastTxnRound: lastTxnRound2 } = await SendXTransactions(1, await generateAccount({ initialFunds: (3).algos() }), algorand) await subscriber.pollOnce() expect(subscribedTxns.length).toBe(1) expect(getWatermark()).toBeGreaterThanOrEqual(lastTxnRound2) // Another subscribed transaction - const { lastTxnRound: lastTxnRound3, txIds: txIds3 } = await SendXTransactions(1, testAccount, algod) + const { lastTxnRound: lastTxnRound3, txIds: txIds3 } = await SendXTransactions(1, testAccount, algorand) await subscriber.pollOnce() expect(subscribedTxns.length).toBe(2) expect(subscribedTxns[1]).toBe(txIds3[0]) @@ -93,16 +91,16 @@ describe('AlgorandSubscriber', () => { }) test('Subscribes to transactions with multiple filters correctly', async () => { - const { algod, testAccount, generateAccount } = localnet.context + const { algorand, testAccount, generateAccount } = localnet.context const randomAccount = await generateAccount({ initialFunds: (3).algos() }) const senders = [await generateAccount({ initialFunds: (5).algos() }), await generateAccount({ initialFunds: (5).algos() })] const sender1TxnIds: string[] = [] let sender1TxnIdsfromBatch: string[] = [] const sender2Rounds: number[] = [] let sender2RoundsfromBatch: number[] = [] - const { lastTxnRound: firstTxnRound, txIds } = await SendXTransactions(1, testAccount, algod) - const { txIds: txIds1 } = await SendXTransactions(2, senders[0], algod) - const { lastTxnRound, txIds: txIds2, txns: txns2 } = await SendXTransactions(2, senders[1], algod) + const { lastTxnRound: firstTxnRound, txIds } = await SendXTransactions(1, testAccount, algorand) + const { txIds: txIds1 } = await SendXTransactions(2, senders[0], algorand) + const { lastTxnRound, txIds: txIds2, txns: txns2 } = await SendXTransactions(2, senders[1], algorand) const { subscriber, getWatermark } = getSubscriber( { testAccount, @@ -113,21 +111,21 @@ describe('AlgorandSubscriber', () => { { name: 'sender1', filter: { - sender: algokit.getSenderAddress(senders[0]), + sender: senders[0].addr, }, mapper: (txs) => Promise.resolve(txs.map((t) => t.id)), }, { name: 'sender2', filter: { - sender: algokit.getSenderAddress(senders[1]), + sender: senders[1].addr, }, mapper: (txs) => Promise.resolve(txs.map((t) => t['confirmed-round']!)), }, ], }, }, - algod, + algorand, ) subscriber.onBatch('sender1', (r) => { sender1TxnIdsfromBatch = r @@ -168,15 +166,15 @@ describe('AlgorandSubscriber', () => { expect(sender2RoundsfromBatch).toEqual(sender2Rounds) // Random transaction - const { lastTxnRound: lastTxnRound2 } = await SendXTransactions(1, randomAccount, algod) + const { lastTxnRound: lastTxnRound2 } = await SendXTransactions(1, randomAccount, algorand) const result2 = await subscriber.pollOnce() expect(result2.subscribedTransactions.length).toBe(0) expect(getWatermark()).toBeGreaterThanOrEqual(lastTxnRound2) // More subscribed transactions - const { txIds: txIds3 } = await SendXTransactions(1, testAccount, algod) - const { txIds: txIds13 } = await SendXTransactions(2, senders[0], algod) - const { lastTxnRound: lastSubscribedRound3, txIds: txIds23, txns: txns23 } = await SendXTransactions(2, senders[1], algod) + const { txIds: txIds3 } = await SendXTransactions(1, testAccount, algorand) + const { txIds: txIds13 } = await SendXTransactions(2, senders[0], algorand) + const { lastTxnRound: lastSubscribedRound3, txIds: txIds23, txns: txns23 } = await SendXTransactions(2, senders[1], algorand) const result3 = await subscriber.pollOnce() console.log( @@ -206,15 +204,15 @@ describe('AlgorandSubscriber', () => { }) test('Subscribes to transactions at regular intervals when started and can be stopped', async () => { - const { algod, testAccount } = localnet.context - const { lastTxnRound, txIds } = await SendXTransactions(1, testAccount, algod) + const { algorand, testAccount } = localnet.context + const { lastTxnRound, txIds } = await SendXTransactions(1, testAccount, algorand) const { subscriber, subscribedTestAccountTxns: subscribedTxns, getWatermark, } = getSubscriber( { testAccount, configOverrides: { maxRoundsToSync: 1, frequencyInSeconds: 0.1 }, initialWatermark: lastTxnRound - 1 }, - algod, + algorand, ) const roundsSynced: number[] = [] @@ -241,8 +239,8 @@ describe('AlgorandSubscriber', () => { }) test('Waits until transaction appears by default when started', async () => { - const { algod, testAccount } = localnet.context - const currentRound = (await algod.status().do())['last-round'] as number + const { algorand, testAccount } = localnet.context + const currentRound = (await algorand.client.algod.status().do())['last-round'] as number const { subscriber, subscribedTestAccountTxns: subscribedTxns, @@ -254,7 +252,7 @@ describe('AlgorandSubscriber', () => { configOverrides: { frequencyInSeconds: 10, waitForBlockWhenAtTip: true, syncBehaviour: 'sync-oldest' }, initialWatermark: currentRound - 1, }, - algod, + algorand, ) const roundsSynced: number[] = [] @@ -266,7 +264,7 @@ describe('AlgorandSubscriber', () => { console.log('Issuing transaction') const pollCountBeforeIssuing = roundsSynced.length - const { lastTxnRound, txIds } = await SendXTransactions(1, testAccount, algod) + const { lastTxnRound, txIds } = await SendXTransactions(1, testAccount, algorand) console.log(`Waiting for up to 2s for round ${lastTxnRound} to get processed`) await waitFor(() => subscribedTxns.length === 1, 5000) @@ -284,16 +282,16 @@ describe('AlgorandSubscriber', () => { }) test('Correctly fires various on* methods', async () => { - const { algod, testAccount, generateAccount } = localnet.context + const { algorand, testAccount, generateAccount } = localnet.context const randomAccount = await generateAccount({ initialFunds: (3).algos() }) - const { txns, txIds } = await SendXTransactions(2, testAccount, algod) - const { txIds: txIds2 } = await SendXTransactions(2, randomAccount, algod) + const { txns, txIds } = await SendXTransactions(2, testAccount, algorand) + const { txIds: txIds2 } = await SendXTransactions(2, randomAccount, algorand) const initialWatermark = Number(txns[0].confirmation!.confirmedRound!) - 1 const eventsEmitted: string[] = [] let pollComplete = false const { subscriber } = getSubscriber( { - testAccount: algokit.randomAccount(), + testAccount: localnet.algorand.account.random().account, initialWatermark, configOverrides: { maxRoundsToSync: 100, @@ -303,19 +301,19 @@ describe('AlgorandSubscriber', () => { { name: 'account1', filter: { - sender: algokit.getSenderAddress(testAccount), + sender: testAccount.addr, }, }, { name: 'account2', filter: { - sender: algokit.getSenderAddress(randomAccount), + sender: randomAccount.addr, }, }, ], }, }, - algod, + algorand, ) subscriber .onBatch('account1', (b) => { @@ -361,15 +359,15 @@ describe('AlgorandSubscriber', () => { }) test('Correctly fires onError method', async () => { - const { algod, testAccount } = localnet.context - const { txns } = await SendXTransactions(2, testAccount, algod) + const { algorand, testAccount } = localnet.context + const { txns } = await SendXTransactions(2, testAccount, algorand) const initialWatermark = Number(txns[0].confirmation!.confirmedRound!) - 1 let complete = false let actualError = undefined const expectedError = new Error('BOOM') const { subscriber } = getSubscriber( { - testAccount: algokit.randomAccount(), + testAccount: localnet.algorand.account.random().account, initialWatermark, configOverrides: { maxRoundsToSync: 100, @@ -379,13 +377,13 @@ describe('AlgorandSubscriber', () => { { name: 'account1', filter: { - sender: algokit.getSenderAddress(testAccount), + sender: testAccount.addr, }, }, ], }, }, - algod, + algorand, ) subscriber diff --git a/tests/scenarios/sync-oldest-start-now.spec.ts b/tests/scenarios/sync-oldest-start-now.spec.ts index 168ac62..e3c18c0 100644 --- a/tests/scenarios/sync-oldest-start-now.spec.ts +++ b/tests/scenarios/sync-oldest-start-now.spec.ts @@ -11,13 +11,13 @@ describe('Subscribing using sync-oldest-start-now', () => { }) test('Processes the current round when starting from beginning of chain', async () => { - const { algod, testAccount } = localnet.context - const { txns, lastTxnRound } = await SendXTransactions(2, testAccount, algod) + const { algorand, testAccount } = localnet.context + const { txns, lastTxnRound } = await SendXTransactions(2, testAccount, algorand) const subscribed = await GetSubscribedTransactionsFromSender( { roundsToSync: 1, syncBehaviour: 'sync-oldest-start-now', watermark: 0, currentRound: lastTxnRound }, testAccount, - algod, + algorand, ) expect(subscribed.currentRound).toBe(lastTxnRound) @@ -29,14 +29,14 @@ describe('Subscribing using sync-oldest-start-now', () => { }) test('Only processes the first transaction after watermark when starting from an earlier round with other transactions', async () => { - const { algod, testAccount } = localnet.context - const { txns, lastTxnRound: olderTxnRound } = await SendXTransactions(2, testAccount, algod) - const { lastTxnRound: currentRound } = await SendXTransactions(1, testAccount, algod) + const { algorand, testAccount } = localnet.context + const { txns, lastTxnRound: olderTxnRound } = await SendXTransactions(2, testAccount, algorand) + const { lastTxnRound: currentRound } = await SendXTransactions(1, testAccount, algorand) const subscribed = await GetSubscribedTransactionsFromSender( { roundsToSync: 1, syncBehaviour: 'sync-oldest', watermark: olderTxnRound - 1, currentRound }, testAccount, - algod, + algorand, ) expect(subscribed.currentRound).toBe(currentRound) @@ -48,8 +48,8 @@ describe('Subscribing using sync-oldest-start-now', () => { }) test('Process multiple transactions', async () => { - const { algod, testAccount } = localnet.context - const { txns, lastTxnRound, rounds } = await SendXTransactions(3, testAccount, algod) + const { algorand, testAccount } = localnet.context + const { txns, lastTxnRound, rounds } = await SendXTransactions(3, testAccount, algorand) const subscribed = await GetSubscribedTransactionsFromSender( { @@ -59,7 +59,7 @@ describe('Subscribing using sync-oldest-start-now', () => { currentRound: lastTxnRound, }, testAccount, - algod, + algorand, ) expect(subscribed.currentRound).toBe(lastTxnRound) diff --git a/tests/scenarios/sync-oldest.spec.ts b/tests/scenarios/sync-oldest.spec.ts index c0734db..1c74dbd 100644 --- a/tests/scenarios/sync-oldest.spec.ts +++ b/tests/scenarios/sync-oldest.spec.ts @@ -11,15 +11,15 @@ describe('Subscribing using sync-oldest', () => { }) test('Only processes the first chain round when starting from beginning of chain', async () => { - const { algod, testAccount, generateAccount } = localnet.context + const { algorand, testAccount, generateAccount } = localnet.context // Ensure that if we are at round 0 there is a different transaction that won't be synced - await SendXTransactions(1, await generateAccount({ initialFunds: (3).algos() }), algod) - const { lastTxnRound } = await SendXTransactions(1, testAccount, algod) + await SendXTransactions(1, await generateAccount({ initialFunds: (3).algos() }), algorand) + const { lastTxnRound } = await SendXTransactions(1, testAccount, algorand) const subscribed = await GetSubscribedTransactionsFromSender( { roundsToSync: 1, syncBehaviour: 'sync-oldest', watermark: 0, currentRound: lastTxnRound }, testAccount, - algod, + algorand, ) expect(subscribed.currentRound).toBe(lastTxnRound) @@ -30,14 +30,14 @@ describe('Subscribing using sync-oldest', () => { }) test('Only processes the first transaction after watermark when starting from an earlier round with other transactions', async () => { - const { algod, testAccount } = localnet.context - const { txns, lastTxnRound: olderTxnRound } = await SendXTransactions(2, testAccount, algod) - const { lastTxnRound: currentRound } = await SendXTransactions(1, testAccount, algod) + const { algorand, testAccount } = localnet.context + const { txns, lastTxnRound: olderTxnRound } = await SendXTransactions(2, testAccount, algorand) + const { lastTxnRound: currentRound } = await SendXTransactions(1, testAccount, algorand) const subscribed = await GetSubscribedTransactionsFromSender( { roundsToSync: 1, syncBehaviour: 'sync-oldest', watermark: olderTxnRound - 1, currentRound }, testAccount, - algod, + algorand, ) expect(subscribed.currentRound).toBe(currentRound) @@ -49,13 +49,13 @@ describe('Subscribing using sync-oldest', () => { }) test('Process multiple transactions', async () => { - const { algod, testAccount } = localnet.context - const { txns, lastTxnRound, rounds } = await SendXTransactions(3, testAccount, algod) + const { algorand, testAccount } = localnet.context + const { txns, lastTxnRound, rounds } = await SendXTransactions(3, testAccount, algorand) const subscribed = await GetSubscribedTransactionsFromSender( { roundsToSync: rounds[1] - rounds[0] + 1, syncBehaviour: 'sync-oldest', watermark: rounds[0] - 1, currentRound: lastTxnRound }, testAccount, - algod, + algorand, ) expect(subscribed.currentRound).toBe(lastTxnRound) diff --git a/tests/scenarios/transform-complex-txn.spec.ts b/tests/scenarios/transform-complex-txn.spec.ts index 9787ab5..cc1efa9 100644 --- a/tests/scenarios/transform-complex-txn.spec.ts +++ b/tests/scenarios/transform-complex-txn.spec.ts @@ -1,4 +1,4 @@ -import * as algokit from '@algorandfoundation/algokit-utils' +import { AlgorandClient, lookupTransactionById } from '@algorandfoundation/algokit-utils' import algosdk from 'algosdk' import { describe, expect, it } from 'vitest' import { getBlocksBulk } from '../../src/block' @@ -8,8 +8,7 @@ import { GetSubscribedTransactions, clearUndefineds, getTransactionInBlockForDif describe('Complex transaction with many nested inner transactions', () => { const txnId = 'QLYC4KMQW5RZRA7W5GYCJ4CUVWWSZKMK2V4X3XFQYSGYCJH6LI4Q' const roundNumber = 35214367 - const algod = algokit.getAlgoClient(algokit.getAlgoNodeConfig('mainnet', 'algod')) - const indexer = algokit.getAlgoIndexerClient(algokit.getAlgoNodeConfig('mainnet', 'indexer')) + const algorand = AlgorandClient.mainNet() it('Can have an inner transaction subscribed correctly from indexer', async () => { const indexerTxns = await GetSubscribedTransactions( @@ -23,8 +22,7 @@ describe('Complex transaction with many nested inner transactions', () => { syncBehaviour: 'catchup-with-indexer', watermark: roundNumber - 1, }, - algod, - indexer, + algorand, ) expect(indexerTxns.subscribedTransactions.length).toBe(1) @@ -171,7 +169,7 @@ describe('Complex transaction with many nested inner transactions', () => { syncBehaviour: 'sync-oldest', watermark: roundNumber - 1, }, - algod, + algorand, ) expect(algodTxns.subscribedTransactions.length).toBe(1) @@ -338,8 +336,8 @@ describe('Complex transaction with many nested inner transactions', () => { }) it('Can be processed correctly from algod raw block', async () => { - const txn = await algokit.lookupTransactionById(txnId, indexer) - const b = (await getBlocksBulk({ startRound: roundNumber, maxRound: roundNumber }, algod))[0] + const txn = await lookupTransactionById(txnId, algorand.client.indexer) + const b = (await getBlocksBulk({ startRound: roundNumber, maxRound: roundNumber }, algorand.client.algod))[0] const intraRoundOffset = txn.transaction['intra-round-offset']! const transformed = await getBlockTransactions(b.block) @@ -683,7 +681,7 @@ describe('Complex transaction with many nested inner transactions', () => { }) it('Transforms axfer without an arcv address', async () => { - const blocks = await getBlocksBulk({ startRound: 39373576, maxRound: 39373576 }, algod) // Contains an axfer opt out inner transaction without an arcv address + const blocks = await getBlocksBulk({ startRound: 39373576, maxRound: 39373576 }, algorand.client.algod) // Contains an axfer opt out inner transaction without an arcv address const blockTransactions = blocks.flatMap((b) => getBlockTransactions(b.block)) expect(blockTransactions.length).toBe(30) @@ -691,7 +689,7 @@ describe('Complex transaction with many nested inner transactions', () => { }) it('Transforms pay without a rcv address', async () => { - const blocks = await getBlocksBulk({ startRound: 39723800, maxRound: 39723800 }, algod) // Contains a pay close account inner transaction without a rcv address + const blocks = await getBlocksBulk({ startRound: 39723800, maxRound: 39723800 }, algorand.client.algod) // Contains a pay close account inner transaction without a rcv address const blockTransactions = blocks.flatMap((b) => getBlockTransactions(b.block)) expect(blockTransactions.length).toBe(486) @@ -699,7 +697,7 @@ describe('Complex transaction with many nested inner transactions', () => { }) it('Produces the correct txID for a non hgi transaction', async () => { - const blocks = await getBlocksBulk({ startRound: 39430981, maxRound: 39430981 }, algod) + const blocks = await getBlocksBulk({ startRound: 39430981, maxRound: 39430981 }, algorand.client.algod) const blockTransactions = blocks.flatMap((b) => getBlockTransactions(b.block)) const transaction = getIndexerTransactionFromAlgodTransaction(blockTransactions[0]) @@ -708,7 +706,7 @@ describe('Complex transaction with many nested inner transactions', () => { }) it('Produces the correct state deltas in an app call transaction', async () => { - const blocks = await getBlocksBulk({ startRound: 39430981, maxRound: 39430981 }, algod) + const blocks = await getBlocksBulk({ startRound: 39430981, maxRound: 39430981 }, algorand.client.algod) const blockTransactions = blocks.flatMap((b) => getBlockTransactions(b.block)) const transaction = getIndexerTransactionFromAlgodTransaction(blockTransactions[9]) @@ -759,7 +757,7 @@ describe('Complex transaction with many nested inner transactions', () => { }) it('Produces base64 encoded programs for an application create transaction', async () => { - const blocks = await getBlocksBulk({ startRound: 34632059, maxRound: 34632059 }, algod) // Contains a appl create transaction with approval and clear state programs + const blocks = await getBlocksBulk({ startRound: 34632059, maxRound: 34632059 }, algorand.client.algod) // Contains a appl create transaction with approval and clear state programs const blockTransactions = blocks.flatMap((b) => getBlockTransactions(b.block)) expect(blockTransactions.length).toBe(14) diff --git a/tests/scenarios/transform-keyreg.spec.ts b/tests/scenarios/transform-keyreg.spec.ts index e522021..9412bf0 100644 --- a/tests/scenarios/transform-keyreg.spec.ts +++ b/tests/scenarios/transform-keyreg.spec.ts @@ -1,4 +1,4 @@ -import * as algokit from '@algorandfoundation/algokit-utils' +import { AlgorandClient } from '@algorandfoundation/algokit-utils' import { TransactionType } from 'algosdk' import { describe, expect, it } from 'vitest' import { GetSubscribedTransactions, clearUndefineds } from '../transactions' @@ -6,8 +6,7 @@ import { GetSubscribedTransactions, clearUndefineds } from '../transactions' describe('Complex transaction with many nested inner transactions', () => { const txnId = 'LSTIW7IBLO4SFPLFAI45WAV3NPXYPX6RWPTZ5KYDL3NX2LTJFXNA' const roundNumber = 34418662 - const algod = algokit.getAlgoClient(algokit.getAlgoNodeConfig('mainnet', 'algod')) - const indexer = algokit.getAlgoIndexerClient(algokit.getAlgoNodeConfig('mainnet', 'indexer')) + const algorand = AlgorandClient.mainNet() it('Can have a keyreg transaction subscribed correctly from indexer', async () => { const indexerTxns = await GetSubscribedTransactions( @@ -21,8 +20,7 @@ describe('Complex transaction with many nested inner transactions', () => { syncBehaviour: 'catchup-with-indexer', watermark: roundNumber - 1, }, - algod, - indexer, + algorand, ) expect(indexerTxns.subscribedTransactions.length).toBe(1) @@ -89,7 +87,7 @@ describe('Complex transaction with many nested inner transactions', () => { syncBehaviour: 'sync-oldest', watermark: roundNumber - 1, }, - algod, + algorand, ) expect(algodTxns.subscribedTransactions.length).toBe(1) diff --git a/tests/scenarios/transform-stpf.spec.ts b/tests/scenarios/transform-stpf.spec.ts index 5b4d1ba..6921177 100644 --- a/tests/scenarios/transform-stpf.spec.ts +++ b/tests/scenarios/transform-stpf.spec.ts @@ -1,4 +1,4 @@ -import * as algokit from '@algorandfoundation/algokit-utils' +import { AlgorandClient } from '@algorandfoundation/algokit-utils' import { TransactionType } from 'algosdk' import { describe, expect, it } from 'vitest' import { GetSubscribedTransactions, clearUndefineds } from '../transactions' @@ -6,8 +6,7 @@ import { GetSubscribedTransactions, clearUndefineds } from '../transactions' describe('State proof transaction', () => { const txnId = 'G2U5DWQRQV7EGQDAHH62EDY22VYPP4VWM3V2S5BLDNXNWFNKRXMQ' const roundNumber = 35600004 - const algod = algokit.getAlgoClient(algokit.getAlgoNodeConfig('mainnet', 'algod')) - const indexer = algokit.getAlgoIndexerClient(algokit.getAlgoNodeConfig('mainnet', 'indexer')) + const algorand = AlgorandClient.mainNet() it('Can have a stpf transaction subscribed correctly from indexer', async () => { const indexerTxns = await GetSubscribedTransactions( @@ -20,8 +19,7 @@ describe('State proof transaction', () => { syncBehaviour: 'catchup-with-indexer', watermark: roundNumber - 1, }, - algod, - indexer, + algorand, ) expect(indexerTxns.subscribedTransactions.length).toBe(1) @@ -2115,7 +2113,7 @@ describe('State proof transaction', () => { syncBehaviour: 'sync-oldest', watermark: roundNumber - 1, }, - algod, + algorand, ) expect(algodTxns.subscribedTransactions.length).toBe(1) diff --git a/tests/testing-app.ts b/tests/testing-app.ts new file mode 100644 index 0000000..82e3134 --- /dev/null +++ b/tests/testing-app.ts @@ -0,0 +1,30 @@ +import { AlgorandClient } from '@algorandfoundation/algokit-utils' +import algosdk, { OnApplicationComplete } from 'algosdk' +import { TestingAppFactory } from './contract/client' + +export async function app(params: { + create: true + algorand: AlgorandClient + creator: algosdk.Account + note?: string +}): ReturnType +export async function app(params: { + create: false + algorand: AlgorandClient + creator: algosdk.Account + note?: string +}): Promise +export async function app(params: { create: boolean; algorand: AlgorandClient; creator: algosdk.Account; note?: string }) { + params.algorand.setSignerFromAccount(params.creator) + const factory = new TestingAppFactory({ + algorand: params.algorand, + }) + + const result = await (params.create ? factory.send : factory.createTransaction).create.bare({ + sender: params.creator.addr, + onComplete: OnApplicationComplete.NoOpOC, + note: params.note, + }) + + return result +} diff --git a/tests/transactions.ts b/tests/transactions.ts index af330a5..7c3c72c 100644 --- a/tests/transactions.ts +++ b/tests/transactions.ts @@ -1,6 +1,6 @@ -import * as algokit from '@algorandfoundation/algokit-utils' -import { SendTransactionFrom, SendTransactionResult } from '@algorandfoundation/algokit-utils/types/transaction' -import algosdk, { Algodv2, Indexer, Transaction } from 'algosdk' +import { algo, AlgorandClient } from '@algorandfoundation/algokit-utils' +import { SendTransactionResult } from '@algorandfoundation/algokit-utils/types/transaction' +import algosdk, { Account, Transaction } from 'algosdk' import { vi } from 'vitest' import { getSubscribedTransactions } from '../src' import type { @@ -11,18 +11,17 @@ import type { TransactionSubscriptionParams, } from '../src/types' -export const SendXTransactions = async (x: number, account: SendTransactionFrom, algod: Algodv2) => { +export const SendXTransactions = async (x: number, account: Account, algorand: AlgorandClient) => { const txns: SendTransactionResult[] = [] for (let i = 0; i < x; i++) { + algorand.setSignerFromAccount(account) txns.push( - await algokit.transferAlgos( - { - amount: (1).algos(), - from: account, - to: account, - }, - algod, - ), + await algorand.send.payment({ + sender: account.addr, + receiver: account.addr, + amount: algo(1), + note: `txn-${i} at ${new Date().toISOString()}`, + }), ) } const lastTxnRound = Number(txns[x - 1].confirmation?.confirmedRound) @@ -45,18 +44,17 @@ export const GetSubscribedTransactions = ( filters: TransactionFilter | NamedTransactionFilter[] arc28Events?: Arc28EventGroup[] }, - algod: Algodv2, - indexer?: Indexer, + algorand: AlgorandClient, ) => { const { roundsToSync, indexerRoundsToSync, syncBehaviour, watermark, currentRound, filters, arc28Events } = subscription if (currentRound !== undefined) { - const existingStatus = algod.status - Object.assign(algod, { + const existingStatus = algorand.client.algod.status + Object.assign(algorand.client.algod, { status: vi.fn().mockImplementation(() => { return { do: async () => { - const status = await existingStatus.apply(algod).do() + const status = await existingStatus.apply(algorand.client.algod).do() status['last-round'] = currentRound return status }, @@ -74,8 +72,8 @@ export const GetSubscribedTransactions = ( watermark: watermark ?? 0, arc28Events, }, - algod, - indexer, + algorand.client.algod, + algorand.client.indexer, ) } @@ -87,20 +85,16 @@ export const GetSubscribedTransactionsFromSender = ( watermark?: number currentRound?: number }, - account: SendTransactionFrom | SendTransactionFrom[], - algod: Algodv2, - indexer?: Indexer, + account: Account | Account[], + algorand: AlgorandClient, ) => { return GetSubscribedTransactions( { ...subscription, filters: - account instanceof Array - ? account.map((a) => algokit.getSenderAddress(a)).map((a) => ({ name: a, filter: { sender: a } })) - : { sender: algokit.getSenderAddress(account) }, + account instanceof Array ? account.map((a) => a.addr).map((a) => ({ name: a, filter: { sender: a } })) : { sender: account.addr }, }, - algod, - indexer, + algorand, ) }