-
Notifications
You must be signed in to change notification settings - Fork 10
feat: support create method in AppClient #401
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: fix/deploy_error_parsing
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -61,6 +61,7 @@ import { AppSpec, arc32ToArc56 } from './app-spec' | |
import { | ||
AppCallMethodCall, | ||
AppCallParams, | ||
AppCreateMethodCall, | ||
AppDeleteMethodCall, | ||
AppDeleteParams, | ||
AppMethodCall, | ||
|
@@ -260,9 +261,9 @@ export interface FundAppAccountParams { | |
/** Source maps for an Algorand app */ | ||
export interface AppSourceMaps { | ||
/** The source map of the approval program */ | ||
approvalSourceMap: SourceMapExport | ||
approvalSourceMap: algosdk.ProgramSourceMap | ||
/** The source map of the clear program */ | ||
clearSourceMap: SourceMapExport | ||
clearSourceMap: algosdk.ProgramSourceMap | ||
} | ||
|
||
export interface SourceMapExport { | ||
|
@@ -353,7 +354,14 @@ export type CallOnComplete = { | |
|
||
/** AppClient common parameters for a bare app call */ | ||
export type AppClientBareCallParams = Expand< | ||
Omit<CommonAppCallParams, 'appId' | 'sender' | 'onComplete'> & { | ||
Omit<CommonAppCallParams, 'appId' | 'sender'> & { | ||
/** The address of the account sending the transaction, if undefined then the app client's defaultSender is used. */ | ||
sender?: Address | string | ||
} | ||
> | ||
|
||
export type AppClientBareCreateParams = Expand< | ||
Omit<CommonAppCallParams, 'appId' | 'sender'> & { | ||
/** The address of the account sending the transaction, if undefined then the app client's defaultSender is used. */ | ||
sender?: Address | string | ||
} | ||
|
@@ -1193,6 +1201,15 @@ export class AppClient { | |
OnApplicationComplete.UpdateApplicationOC, | ||
) as AppUpdateParams | ||
}, | ||
create: async (params?: AppClientBareCallParams & AppClientCompilationParams) => { | ||
return this.getBareParams( | ||
{ | ||
...params, | ||
...(await this.compile(params)), | ||
}, | ||
params?.onComplete, | ||
) as AppUpdateParams | ||
}, | ||
/** Return params for an opt-in call */ | ||
optIn: (params?: AppClientBareCallParams) => { | ||
return this.getBareParams(params, OnApplicationComplete.OptInOC) as AppCallParams | ||
|
@@ -1222,6 +1239,9 @@ export class AppClient { | |
update: async (params?: AppClientBareCallParams & AppClientCompilationParams) => { | ||
return this._algorand.createTransaction.appUpdate(await this.params.bare.update(params)) | ||
}, | ||
create: async (params?: AppClientBareCallParams & AppClientCompilationParams) => { | ||
return this._algorand.createTransaction.appCreate(await this.params.bare.update(params)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should that be create rather than update? |
||
}, | ||
/** Returns a transaction for an opt-in call */ | ||
optIn: (params?: AppClientBareCallParams) => { | ||
return this._algorand.createTransaction.appCall(this.params.bare.optIn(params)) | ||
|
@@ -1255,6 +1275,16 @@ export class AppClient { | |
...(compiled as Partial<AppCompilationResult>), | ||
} | ||
}, | ||
create: async (params?: AppClientBareCallParams & AppClientCompilationParams & SendParams) => { | ||
const compiled = await this.compile(params) | ||
const results = { | ||
...(await this._algorand.send.appCreate(await this.params.bare.create(params))), | ||
...(compiled as Partial<AppCompilationResult>), | ||
} | ||
|
||
this._appId = results.appId | ||
return results | ||
}, | ||
/** Signs and sends an opt-in call */ | ||
optIn: (params?: AppClientBareCallParams & SendParams) => { | ||
return this._algorand.send.appCall(this.params.bare.optIn(params)) | ||
|
@@ -1307,6 +1337,19 @@ export class AppClient { | |
OnApplicationComplete.UpdateApplicationOC, | ||
)) satisfies AppUpdateMethodCall | ||
}, | ||
create: async (params: AppClientMethodCallParams & AppClientCompilationParams) => { | ||
if (params.onComplete === OnApplicationComplete.ClearStateOC) { | ||
throw new Error(`Cannot create with an OnComplete value of ${params.onComplete}`) | ||
} | ||
|
||
return (await this.getABIParams( | ||
{ | ||
...params, | ||
...(await this.compile(params)), | ||
}, | ||
params.onComplete, | ||
)) satisfies AppCreateMethodCall | ||
}, | ||
/** | ||
* Return params for an opt-in ABI call | ||
* @param params The parameters for the opt-in ABI method call | ||
|
@@ -1364,6 +1407,24 @@ export class AppClient { | |
...(compiled as Partial<AppCompilationResult>), | ||
} | ||
}, | ||
/** | ||
* Sign and send transactions for an update ABI call, including deploy-time TEAL template replacements and compilation if provided | ||
* @param params The parameters for the update ABI method call | ||
* @returns The result of sending the update ABI method call | ||
*/ | ||
create: async (params: AppClientMethodCallParams & AppClientCompilationParams & SendParams) => { | ||
const compiled = await this.compile(params) | ||
const results = { | ||
...(await this.processMethodCallReturn( | ||
this._algorand.send.appCreateMethodCall(await this.params.create({ ...params })), | ||
getArc56Method(params.method, this._appSpec), | ||
)), | ||
...(compiled as Partial<AppCompilationResult>), | ||
} | ||
|
||
this._appId = results.appId | ||
return results | ||
}, | ||
/** | ||
* Sign and send transactions for an opt-in ABI call | ||
* @param params The parameters for the opt-in ABI method call | ||
|
@@ -1477,6 +1538,9 @@ export class AppClient { | |
update: async (params: AppClientMethodCallParams & AppClientCompilationParams) => { | ||
return this._algorand.createTransaction.appUpdateMethodCall(await this.params.update(params)) | ||
}, | ||
create: async (params: AppClientMethodCallParams & AppClientCompilationParams) => { | ||
return this._algorand.createTransaction.appCreateMethodCall(await this.params.update(params)) | ||
}, | ||
/** | ||
* Return transactions for an opt-in ABI call | ||
* @param params The parameters for the opt-in ABI method call | ||
|
@@ -1534,7 +1598,7 @@ export class AppClient { | |
private getBareParams< | ||
TParams extends { sender?: Address | string; signer?: TransactionSigner | TransactionSignerAccount } | undefined, | ||
TOnComplete extends OnApplicationComplete, | ||
>(params: TParams, onComplete: TOnComplete) { | ||
>(params: TParams, onComplete?: TOnComplete) { | ||
return { | ||
...params, | ||
appId: this._appId, | ||
|
@@ -1552,7 +1616,7 @@ export class AppClient { | |
args?: AppClientMethodCallParams['args'] | ||
}, | ||
TOnComplete extends OnApplicationComplete, | ||
>(params: TParams, onComplete: TOnComplete) { | ||
>(params: TParams, onComplete?: TOnComplete) { | ||
const sender = this.getSender(params.sender) | ||
const method = getArc56Method(params.method, this._appSpec) | ||
const args = await this.getABIArgsWithDefaultValues(params.method, params.args, sender) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,6 +25,7 @@ import { | |
} from './composer' | ||
import { Expand } from './expand' | ||
import { ConfirmedTransactionResult, SendParams } from './transaction' | ||
import { AppClient } from './app-client' | ||
|
||
/** Params to specify an update transaction for an app deployment */ | ||
export type DeployAppUpdateParams = Expand<Omit<AppUpdateParams, 'appId' | 'approvalProgram' | 'clearStateProgram'>> | ||
|
@@ -252,18 +253,18 @@ export class AppDeployer { | |
) | ||
const result = await ('method' in updateParams | ||
? this._transactionSender.appUpdateMethodCall({ | ||
...updateParams, | ||
...sendParams, | ||
appId: existingApp.appId, | ||
approvalProgram, | ||
clearStateProgram, | ||
...updateParams, | ||
...sendParams, | ||
}) | ||
: this._transactionSender.appUpdate({ | ||
...updateParams, | ||
...sendParams, | ||
appId: existingApp.appId, | ||
approvalProgram, | ||
clearStateProgram, | ||
...updateParams, | ||
...sendParams, | ||
})) | ||
const appMetadata: AppMetadata = { | ||
appId: existingApp.appId, | ||
|
@@ -300,9 +301,9 @@ export class AppDeployer { | |
} | ||
const createIndex = await composer.count() | ||
if ('method' in deleteParams) { | ||
composer.addAppDeleteMethodCall({ appId: existingApp.appId, ...deleteParams }) | ||
composer.addAppDeleteMethodCall({ ...deleteParams, appId: existingApp.appId }) | ||
} else { | ||
composer.addAppDelete({ appId: existingApp.appId, ...deleteParams }) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are these changes (in a few places) deliberate? In general I was pretty careful about ordering of spreading but it’s possible I got some wrong There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes because we are now getting the params from the app client's params methods, which include the app ID of the client. Previously there was no app ID being passed in |
||
composer.addAppDelete({ ...deleteParams, appId: existingApp.appId }) | ||
} | ||
const result = await composer.send({ ...sendParams }) | ||
const confirmation = result.confirmations.at(createIndex - 1)! | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be extending reliance on algosdk types externally which I'm not sure we want to do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah good catch. Didn't realize the SDK used a class