diff --git a/examples/helloworld/client.spec.ts b/examples/helloworld/client.spec.ts index 35def18..7dc4c88 100644 --- a/examples/helloworld/client.spec.ts +++ b/examples/helloworld/client.spec.ts @@ -71,4 +71,23 @@ describe('hello world typed client', () => { expect(result.returns[1]).toBe('Hello, World!') expect(result.txIds.length).toBe(5) }) + + test('Simulates hello', async () => { + const { algod, indexer, testAccount } = localnet.context + const client = new HelloWorldAppClient( + { + resolveBy: 'creatorAndName', + sender: testAccount, + creatorAddress: testAccount.addr, + findExistingUsing: indexer, + }, + algod, + ) + await client.deploy() + + const response = await client.compose().hello({ name: 'mate' }).simulate() + + expect(response.methodResults[0].returnValue).toBe('Hello, mate') + expect(response.simulateResponse.txnGroups[0].appBudgetConsumed).toBeLessThan(50) + }) }) diff --git a/examples/helloworld/client.ts b/examples/helloworld/client.ts index c338de8..cf4b959 100644 --- a/examples/helloworld/client.ts +++ b/examples/helloworld/client.ts @@ -23,7 +23,7 @@ import type { } 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 { TransactionWithSigner } from 'algosdk' +import type { ABIResult, TransactionWithSigner, modelsv2 } from 'algosdk' import { Algodv2, OnApplicationComplete, Transaction, AtomicTransactionComposer } from 'algosdk' export const APP_SPEC: AppSpec = { "hints": { @@ -554,6 +554,11 @@ export class HelloWorldAppClient { await promiseChain return atc }, + async simulate() { + await promiseChain + const result = await atc.simulate(client.algod) + return result + }, async execute() { await promiseChain const result = await algokit.sendAtomicTransactionComposer({ atc, sendParams: {} }, client.algod) @@ -634,10 +639,18 @@ export type HelloWorldAppComposer = { */ atc(): Promise /** - * Executes the transaction group and returns an array of results + * Simulates the transaction group and returns the result + */ + simulate(): Promise + /** + * Executes the transaction group and returns the results */ execute(): Promise> } +export type HelloWorldAppComposerSimulateResult = { + methodResults: ABIResult[] + simulateResponse: modelsv2.SimulateResponse +} export type HelloWorldAppComposerResults = { returns: TReturns groupId: string diff --git a/examples/lifecycle/client.ts b/examples/lifecycle/client.ts index 341a168..237f3ce 100644 --- a/examples/lifecycle/client.ts +++ b/examples/lifecycle/client.ts @@ -23,7 +23,7 @@ import type { } 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 { TransactionWithSigner } from 'algosdk' +import type { ABIResult, TransactionWithSigner, modelsv2 } from 'algosdk' import { Algodv2, OnApplicationComplete, Transaction, AtomicTransactionComposer } from 'algosdk' export const APP_SPEC: AppSpec = { "hints": { @@ -666,6 +666,11 @@ export class LifeCycleAppClient { await promiseChain return atc }, + async simulate() { + await promiseChain + const result = await atc.simulate(client.algod) + return result + }, async execute() { await promiseChain const result = await algokit.sendAtomicTransactionComposer({ atc, sendParams: {} }, client.algod) @@ -729,10 +734,18 @@ export type LifeCycleAppComposer = { */ atc(): Promise /** - * Executes the transaction group and returns an array of results + * Simulates the transaction group and returns the result + */ + simulate(): Promise + /** + * Executes the transaction group and returns the results */ execute(): Promise> } +export type LifeCycleAppComposerSimulateResult = { + methodResults: ABIResult[] + simulateResponse: modelsv2.SimulateResponse +} export type LifeCycleAppComposerResults = { returns: TReturns groupId: string diff --git a/examples/state/client.ts b/examples/state/client.ts index f558a12..5732ea4 100644 --- a/examples/state/client.ts +++ b/examples/state/client.ts @@ -23,7 +23,7 @@ import type { } 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 { TransactionWithSigner } from 'algosdk' +import type { ABIResult, TransactionWithSigner, modelsv2 } from 'algosdk' import { Algodv2, OnApplicationComplete, Transaction, AtomicTransactionComposer } from 'algosdk' export const APP_SPEC: AppSpec = { "hints": { @@ -1572,6 +1572,11 @@ export class StateAppClient { await promiseChain return atc }, + async simulate() { + await promiseChain + const result = await atc.simulate(client.algod) + return result + }, async execute() { await promiseChain const result = await algokit.sendAtomicTransactionComposer({ atc, sendParams: {} }, client.algod) @@ -1768,10 +1773,18 @@ export type StateAppComposer = { */ atc(): Promise /** - * Executes the transaction group and returns an array of results + * Simulates the transaction group and returns the result + */ + simulate(): Promise + /** + * Executes the transaction group and returns the results */ execute(): Promise> } +export type StateAppComposerSimulateResult = { + methodResults: ABIResult[] + simulateResponse: modelsv2.SimulateResponse +} export type StateAppComposerResults = { returns: TReturns groupId: string diff --git a/examples/voting/client.ts b/examples/voting/client.ts index 8e61207..e83b647 100644 --- a/examples/voting/client.ts +++ b/examples/voting/client.ts @@ -23,7 +23,7 @@ import type { } 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 { TransactionWithSigner } from 'algosdk' +import type { ABIResult, TransactionWithSigner, modelsv2 } from 'algosdk' import { Algodv2, OnApplicationComplete, Transaction, AtomicTransactionComposer } from 'algosdk' export const APP_SPEC: AppSpec = { "hints": { @@ -925,6 +925,11 @@ export class VotingRoundAppClient { await promiseChain return atc }, + async simulate() { + await promiseChain + const result = await atc.simulate(client.algod) + return result + }, async execute() { await promiseChain const result = await algokit.sendAtomicTransactionComposer({ atc, sendParams: {} }, client.algod) @@ -1008,10 +1013,18 @@ export type VotingRoundAppComposer = { */ atc(): Promise /** - * Executes the transaction group and returns an array of results + * Simulates the transaction group and returns the result + */ + simulate(): Promise + /** + * Executes the transaction group and returns the results */ execute(): Promise> } +export type VotingRoundAppComposerSimulateResult = { + methodResults: ABIResult[] + simulateResponse: modelsv2.SimulateResponse +} export type VotingRoundAppComposerResults = { returns: TReturns groupId: string diff --git a/package.json b/package.json index d700067..66d0a31 100644 --- a/package.json +++ b/package.json @@ -134,4 +134,4 @@ "@semantic-release/github" ] } -} +} \ No newline at end of file diff --git a/src/client/call-composer-types.ts b/src/client/call-composer-types.ts index 19c3eae..34d2ebd 100644 --- a/src/client/call-composer-types.ts +++ b/src/client/call-composer-types.ts @@ -56,12 +56,23 @@ export function* callComposerType(ctx: GeneratorContext): DocumentParts { yield `atc(): Promise` yield* jsDoc({ - description: 'Executes the transaction group and returns an array of results', + description: 'Simulates the transaction group and returns the result', + }) + yield `simulate(): Promise<${name}ComposerSimulateResult>` + + yield* jsDoc({ + description: 'Executes the transaction group and returns the results', }) yield `execute(): Promise<${name}ComposerResults>` yield DecIndentAndCloseBlock + yield `export type ${name}ComposerSimulateResult = {` + yield IncIndent + yield `methodResults: ABIResult[]` + yield `simulateResponse: modelsv2.SimulateResponse` + yield DecIndentAndCloseBlock + yield `export type ${name}ComposerResults = {` yield IncIndent yield `returns: TReturns` diff --git a/src/client/call-composer.ts b/src/client/call-composer.ts index ffc66b3..67c8480 100644 --- a/src/client/call-composer.ts +++ b/src/client/call-composer.ts @@ -39,6 +39,14 @@ export function* composeMethod(ctx: GeneratorContext): DocumentParts { yield DecIndent yield '},' + yield `async simulate() {` + yield IncIndent + yield `await promiseChain` + yield `const result = await atc.simulate(client.algod)` + yield `return result` + yield DecIndent + yield '},' + yield `async execute() {` yield IncIndent yield `await promiseChain` diff --git a/src/client/imports.ts b/src/client/imports.ts index 2f5d31c..98014fc 100644 --- a/src/client/imports.ts +++ b/src/client/imports.ts @@ -20,6 +20,6 @@ import type { } 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 { TransactionWithSigner } from 'algosdk' +import type { ABIResult, TransactionWithSigner, modelsv2 } from 'algosdk' import { Algodv2, OnApplicationComplete, Transaction, AtomicTransactionComposer } from 'algosdk'` }