Skip to content

Commit

Permalink
Merge pull request #91 from algorandfoundation/fix/create-update-retu…
Browse files Browse the repository at this point in the history
…rn-type-alt

fix: Correcting the return type of create and update calls, fixes #89
  • Loading branch information
robdmoore authored Jan 25, 2024
2 parents 8b8b345 + 2e6f2fc commit b751c57
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 67 deletions.
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ npx --yes @algorandfoundation/algokit-client-generator generate -a ./applicatio
Alternatively, a client can be generated from code by invoking the `generate` function paired with either `writeDocumentPartsToString` or `writeDocumentPartsToStream` depending on your needs. We also expose helpers to optionally load and validate an application.json file.

```ts
import fs from 'fs
import fs from 'fs'
import {
writeDocumentPartsToStream,
writeDocumentPartsToString,
generate,
loadApplicationJson,
validateApplicationJson
validateApplicationJson,
} from '@algorandfoundation/algokit-client-generator'
import appJson from './application.json'

Expand All @@ -39,10 +39,9 @@ const appJsonFromObject = validateApplicationJson(appJson)
const fileStream = fs.createWriteStream('./client.ts', {
flags: 'w',
})
writeDocumentPartsToStream(generate(appJsonFromFile, fileStream)
writeDocumentPartsToStream(generate(appJsonFromFile, fileStream))

const clientAsString = writeDocumentPartsToString(appJsonFromObject)

```

For details on how to use the generated client see the more detailed [usage docs](./docs/usage.md)
Expand Down Expand Up @@ -96,6 +95,8 @@ poetry run python -m examples

Or in Visual Studio Code you can use the default build task (Ctrl+Shift+B).

To regenerate the generated clients run `npm run update-approvals`.

### Continuous Integration / Continuous Deployment (CI/CD)

This project uses [GitHub Actions](https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions) to define CI/CD workflows, which are located in the [`.github/workflows`](./.github/workflows) folder.
Expand Down
25 changes: 15 additions & 10 deletions examples/helloworld/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
*/
import * as algokit from '@algorandfoundation/algokit-utils'
import type {
ABIAppCallArg,
AppCallTransactionResult,
AppCallTransactionResultOfType,
AppCompilationResult,
AppReference,
AppState,
CoreAppCallArgs,
RawAppCallArgs,
AppState,
TealTemplateParams,
ABIAppCallArg,
} from '@algorandfoundation/algokit-utils/types/app'
import type {
AppClientCallCoreParams,
Expand Down Expand Up @@ -148,6 +150,9 @@ export type BinaryState = {
asString(): string
}

export type AppCreateCallTransactionResult = AppCallTransactionResult & Partial<AppCompilationResult> & AppReference
export type AppUpdateCallTransactionResult = AppCallTransactionResult & Partial<AppCompilationResult>

/**
* Defines the types of available calls and state of the HelloWorldApp smart contract.
*/
Expand Down Expand Up @@ -375,14 +380,14 @@ export class HelloWorldAppClient {
* @param returnValueFormatter An optional delegate to format the return value if required
* @returns The smart contract response with an updated return value
*/
protected mapReturnValue<TReturn>(result: AppCallTransactionResult, returnValueFormatter?: (value: any) => TReturn): AppCallTransactionResultOfType<TReturn> {
protected mapReturnValue<TReturn, TResult extends AppCallTransactionResult = AppCallTransactionResult>(result: AppCallTransactionResult, returnValueFormatter?: (value: any) => TReturn): AppCallTransactionResultOfType<TReturn> & 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 }
return { ...result, return: returnValue } as AppCallTransactionResultOfType<TReturn> & TResult
}

/**
Expand Down Expand Up @@ -427,8 +432,8 @@ export class HelloWorldAppClient {
* @param args The arguments for the bare call
* @returns The create result
*/
bare(args: BareCallArgs & AppClientCallCoreParams & AppClientCompilationParams & CoreAppCallArgs & (OnCompleteNoOp) = {}): Promise<AppCallTransactionResultOfType<undefined>> {
return $this.appClient.create(args) as unknown as Promise<AppCallTransactionResultOfType<undefined>>
async bare(args: BareCallArgs & AppClientCallCoreParams & AppClientCompilationParams & CoreAppCallArgs & (OnCompleteNoOp) = {}) {
return $this.mapReturnValue<undefined, AppCreateCallTransactionResult>(await $this.appClient.create(args))
},
}
}
Expand All @@ -445,8 +450,8 @@ export class HelloWorldAppClient {
* @param args The arguments for the bare call
* @returns The update result
*/
bare(args: BareCallArgs & AppClientCallCoreParams & AppClientCompilationParams & CoreAppCallArgs = {}): Promise<AppCallTransactionResultOfType<undefined>> {
return $this.appClient.update(args) as unknown as Promise<AppCallTransactionResultOfType<undefined>>
async bare(args: BareCallArgs & AppClientCallCoreParams & AppClientCompilationParams & CoreAppCallArgs = {}) {
return $this.mapReturnValue<undefined, AppUpdateCallTransactionResult>(await $this.appClient.update(args))
},
}
}
Expand All @@ -463,8 +468,8 @@ export class HelloWorldAppClient {
* @param args The arguments for the bare call
* @returns The delete result
*/
bare(args: BareCallArgs & AppClientCallCoreParams & CoreAppCallArgs = {}): Promise<AppCallTransactionResultOfType<undefined>> {
return $this.appClient.delete(args) as unknown as Promise<AppCallTransactionResultOfType<undefined>>
async bare(args: BareCallArgs & AppClientCallCoreParams & CoreAppCallArgs = {}) {
return $this.mapReturnValue<undefined>(await $this.appClient.delete(args))
},
}
}
Expand Down
29 changes: 17 additions & 12 deletions examples/lifecycle/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
*/
import * as algokit from '@algorandfoundation/algokit-utils'
import type {
ABIAppCallArg,
AppCallTransactionResult,
AppCallTransactionResultOfType,
AppCompilationResult,
AppReference,
AppState,
CoreAppCallArgs,
RawAppCallArgs,
AppState,
TealTemplateParams,
ABIAppCallArg,
} from '@algorandfoundation/algokit-utils/types/app'
import type {
AppClientCallCoreParams,
Expand Down Expand Up @@ -194,6 +196,9 @@ export type BinaryState = {
asString(): string
}

export type AppCreateCallTransactionResult = AppCallTransactionResult & Partial<AppCompilationResult> & AppReference
export type AppUpdateCallTransactionResult = AppCallTransactionResult & Partial<AppCompilationResult>

/**
* Defines the types of available calls and state of the LifeCycleApp smart contract.
*/
Expand Down Expand Up @@ -442,14 +447,14 @@ export class LifeCycleAppClient {
* @param returnValueFormatter An optional delegate to format the return value if required
* @returns The smart contract response with an updated return value
*/
protected mapReturnValue<TReturn>(result: AppCallTransactionResult, returnValueFormatter?: (value: any) => TReturn): AppCallTransactionResultOfType<TReturn> {
protected mapReturnValue<TReturn, TResult extends AppCallTransactionResult = AppCallTransactionResult>(result: AppCallTransactionResult, returnValueFormatter?: (value: any) => TReturn): AppCallTransactionResultOfType<TReturn> & 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 }
return { ...result, return: returnValue } as AppCallTransactionResultOfType<TReturn> & TResult
}

/**
Expand Down Expand Up @@ -492,8 +497,8 @@ export class LifeCycleAppClient {
* @param args The arguments for the bare call
* @returns The create result
*/
bare(args: BareCallArgs & AppClientCallCoreParams & AppClientCompilationParams & CoreAppCallArgs & (OnCompleteNoOp | OnCompleteOptIn) = {}): Promise<AppCallTransactionResultOfType<undefined>> {
return $this.appClient.create(args) as unknown as Promise<AppCallTransactionResultOfType<undefined>>
async bare(args: BareCallArgs & AppClientCallCoreParams & AppClientCompilationParams & CoreAppCallArgs & (OnCompleteNoOp | OnCompleteOptIn) = {}) {
return $this.mapReturnValue<undefined, AppCreateCallTransactionResult>(await $this.appClient.create(args))
},
/**
* Creates a new instance of the LifeCycleApp smart contract using the create(string)string ABI method.
Expand All @@ -502,8 +507,8 @@ export class LifeCycleAppClient {
* @param params Any additional parameters for the call
* @returns The create result: The formatted greeting
*/
async createStringString(args: MethodArgs<'create(string)string'>, params: AppClientCallCoreParams & AppClientCompilationParams & (OnCompleteNoOp) = {}): Promise<AppCallTransactionResultOfType<MethodReturn<'create(string)string'>>> {
return $this.mapReturnValue(await $this.appClient.create(LifeCycleAppCallFactory.create.createStringString(args, params)))
async createStringString(args: MethodArgs<'create(string)string'>, params: AppClientCallCoreParams & AppClientCompilationParams & (OnCompleteNoOp) = {}) {
return $this.mapReturnValue<MethodReturn<'create(string)string'>, AppCreateCallTransactionResult>(await $this.appClient.create(LifeCycleAppCallFactory.create.createStringString(args, params)))
},
/**
* Creates a new instance of the LifeCycleApp smart contract using the create(string,uint32)void ABI method.
Expand All @@ -512,8 +517,8 @@ export class LifeCycleAppClient {
* @param params Any additional parameters for the call
* @returns The create result
*/
async createStringUint32Void(args: MethodArgs<'create(string,uint32)void'>, params: AppClientCallCoreParams & AppClientCompilationParams & (OnCompleteNoOp) = {}): Promise<AppCallTransactionResultOfType<MethodReturn<'create(string,uint32)void'>>> {
return $this.mapReturnValue(await $this.appClient.create(LifeCycleAppCallFactory.create.createStringUint32Void(args, params)))
async createStringUint32Void(args: MethodArgs<'create(string,uint32)void'>, params: AppClientCallCoreParams & AppClientCompilationParams & (OnCompleteNoOp) = {}) {
return $this.mapReturnValue<MethodReturn<'create(string,uint32)void'>, AppCreateCallTransactionResult>(await $this.appClient.create(LifeCycleAppCallFactory.create.createStringUint32Void(args, params)))
},
}
}
Expand All @@ -530,8 +535,8 @@ export class LifeCycleAppClient {
* @param args The arguments for the bare call
* @returns The update result
*/
bare(args: BareCallArgs & AppClientCallCoreParams & AppClientCompilationParams & CoreAppCallArgs = {}): Promise<AppCallTransactionResultOfType<undefined>> {
return $this.appClient.update(args) as unknown as Promise<AppCallTransactionResultOfType<undefined>>
async bare(args: BareCallArgs & AppClientCallCoreParams & AppClientCompilationParams & CoreAppCallArgs = {}) {
return $this.mapReturnValue<undefined, AppUpdateCallTransactionResult>(await $this.appClient.update(args))
},
}
}
Expand Down
41 changes: 23 additions & 18 deletions examples/state/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
*/
import * as algokit from '@algorandfoundation/algokit-utils'
import type {
ABIAppCallArg,
AppCallTransactionResult,
AppCallTransactionResultOfType,
AppCompilationResult,
AppReference,
AppState,
CoreAppCallArgs,
RawAppCallArgs,
AppState,
TealTemplateParams,
ABIAppCallArg,
} from '@algorandfoundation/algokit-utils/types/app'
import type {
AppClientCallCoreParams,
Expand Down Expand Up @@ -523,6 +525,9 @@ export type BinaryState = {
asString(): string
}

export type AppCreateCallTransactionResult = AppCallTransactionResult & Partial<AppCompilationResult> & AppReference
export type AppUpdateCallTransactionResult = AppCallTransactionResult & Partial<AppCompilationResult>

/**
* Defines the types of available calls and state of the StateApp smart contract.
*/
Expand Down Expand Up @@ -1077,14 +1082,14 @@ export class StateAppClient {
* @param returnValueFormatter An optional delegate to format the return value if required
* @returns The smart contract response with an updated return value
*/
protected mapReturnValue<TReturn>(result: AppCallTransactionResult, returnValueFormatter?: (value: any) => TReturn): AppCallTransactionResultOfType<TReturn> {
protected mapReturnValue<TReturn, TResult extends AppCallTransactionResult = AppCallTransactionResult>(result: AppCallTransactionResult, returnValueFormatter?: (value: any) => TReturn): AppCallTransactionResultOfType<TReturn> & 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 }
return { ...result, return: returnValue } as AppCallTransactionResultOfType<TReturn> & TResult
}

/**
Expand Down Expand Up @@ -1129,8 +1134,8 @@ export class StateAppClient {
* @param args The arguments for the bare call
* @returns The create result
*/
bare(args: BareCallArgs & AppClientCallCoreParams & AppClientCompilationParams & CoreAppCallArgs & (OnCompleteNoOp | OnCompleteOptIn) = {}): Promise<AppCallTransactionResultOfType<undefined>> {
return $this.appClient.create(args) as unknown as Promise<AppCallTransactionResultOfType<undefined>>
async bare(args: BareCallArgs & AppClientCallCoreParams & AppClientCompilationParams & CoreAppCallArgs & (OnCompleteNoOp | OnCompleteOptIn) = {}) {
return $this.mapReturnValue<undefined, AppCreateCallTransactionResult>(await $this.appClient.create(args))
},
/**
* Creates a new instance of the StateApp smart contract using the create_abi(string)string ABI method.
Expand All @@ -1139,8 +1144,8 @@ export class StateAppClient {
* @param params Any additional parameters for the call
* @returns The create result
*/
async createAbi(args: MethodArgs<'create_abi(string)string'>, params: AppClientCallCoreParams & AppClientCompilationParams & (OnCompleteNoOp) = {}): Promise<AppCallTransactionResultOfType<MethodReturn<'create_abi(string)string'>>> {
return $this.mapReturnValue(await $this.appClient.create(StateAppCallFactory.create.createAbi(args, params)))
async createAbi(args: MethodArgs<'create_abi(string)string'>, params: AppClientCallCoreParams & AppClientCompilationParams & (OnCompleteNoOp) = {}) {
return $this.mapReturnValue<MethodReturn<'create_abi(string)string'>, AppCreateCallTransactionResult>(await $this.appClient.create(StateAppCallFactory.create.createAbi(args, params)))
},
}
}
Expand All @@ -1157,8 +1162,8 @@ export class StateAppClient {
* @param args The arguments for the bare call
* @returns The update result
*/
bare(args: BareCallArgs & AppClientCallCoreParams & AppClientCompilationParams & CoreAppCallArgs = {}): Promise<AppCallTransactionResultOfType<undefined>> {
return $this.appClient.update(args) as unknown as Promise<AppCallTransactionResultOfType<undefined>>
async bare(args: BareCallArgs & AppClientCallCoreParams & AppClientCompilationParams & CoreAppCallArgs = {}) {
return $this.mapReturnValue<undefined, AppUpdateCallTransactionResult>(await $this.appClient.update(args))
},
/**
* Updates an existing instance of the StateApp smart contract using the update_abi(string)string ABI method.
Expand All @@ -1167,8 +1172,8 @@ export class StateAppClient {
* @param params Any additional parameters for the call
* @returns The update result
*/
async updateAbi(args: MethodArgs<'update_abi(string)string'>, params: AppClientCallCoreParams & AppClientCompilationParams = {}): Promise<AppCallTransactionResultOfType<MethodReturn<'update_abi(string)string'>>> {
return $this.mapReturnValue(await $this.appClient.update(StateAppCallFactory.update.updateAbi(args, params)))
async updateAbi(args: MethodArgs<'update_abi(string)string'>, params: AppClientCallCoreParams & AppClientCompilationParams = {}) {
return $this.mapReturnValue<MethodReturn<'update_abi(string)string'>, AppUpdateCallTransactionResult>(await $this.appClient.update(StateAppCallFactory.update.updateAbi(args, params)))
},
}
}
Expand All @@ -1185,8 +1190,8 @@ export class StateAppClient {
* @param args The arguments for the bare call
* @returns The delete result
*/
bare(args: BareCallArgs & AppClientCallCoreParams & CoreAppCallArgs = {}): Promise<AppCallTransactionResultOfType<undefined>> {
return $this.appClient.delete(args) as unknown as Promise<AppCallTransactionResultOfType<undefined>>
async bare(args: BareCallArgs & AppClientCallCoreParams & CoreAppCallArgs = {}) {
return $this.mapReturnValue<undefined>(await $this.appClient.delete(args))
},
/**
* Deletes an existing instance of the StateApp smart contract using the delete_abi(string)string ABI method.
Expand All @@ -1195,8 +1200,8 @@ export class StateAppClient {
* @param params Any additional parameters for the call
* @returns The delete result
*/
async deleteAbi(args: MethodArgs<'delete_abi(string)string'>, params: AppClientCallCoreParams = {}): Promise<AppCallTransactionResultOfType<MethodReturn<'delete_abi(string)string'>>> {
return $this.mapReturnValue(await $this.appClient.delete(StateAppCallFactory.delete.deleteAbi(args, params)))
async deleteAbi(args: MethodArgs<'delete_abi(string)string'>, params: AppClientCallCoreParams = {}) {
return $this.mapReturnValue<MethodReturn<'delete_abi(string)string'>>(await $this.appClient.delete(StateAppCallFactory.delete.deleteAbi(args, params)))
},
}
}
Expand All @@ -1214,8 +1219,8 @@ export class StateAppClient {
* @param params Any additional parameters for the call
* @returns The optIn result
*/
async optIn(args: MethodArgs<'opt_in()void'>, params: AppClientCallCoreParams = {}): Promise<AppCallTransactionResultOfType<MethodReturn<'opt_in()void'>>> {
return $this.mapReturnValue(await $this.appClient.optIn(StateAppCallFactory.optIn.optIn(args, params)))
async optIn(args: MethodArgs<'opt_in()void'>, params: AppClientCallCoreParams = {}) {
return $this.mapReturnValue<MethodReturn<'opt_in()void'>>(await $this.appClient.optIn(StateAppCallFactory.optIn.optIn(args, params)))
},
}
}
Expand Down
Loading

0 comments on commit b751c57

Please sign in to comment.