Skip to content

Commit

Permalink
feat: support extra program pages when deploying an app
Browse files Browse the repository at this point in the history
  • Loading branch information
neilcampbell committed Jan 6, 2025
1 parent d9c0a97 commit 4d8efe5
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 14 deletions.
12 changes: 6 additions & 6 deletions src/features/app-interfaces/components/create/deploy-app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { isArc32AppSpec, isArc56AppSpec } from '@/features/common/utils'
import { asAppCallTransactionParams, asMethodCallParams } from '@/features/transaction-wizard/mappers'
import { asArc56AppSpec, asMethodDefinitions } from '@/features/applications/mappers'
import { Arc32AppSpec, TemplateParamType } from '../../data/types'
import { CreateOnComplete } from '@algorandfoundation/algokit-utils/types/app-factory'
import { CreateOnComplete, CreateSchema } from '@algorandfoundation/algokit-utils/types/app-factory'
import { AppClientBareCallParams, AppClientMethodCallParams } from '@algorandfoundation/algokit-utils/types/app-client'
import { MethodDefinition } from '@/features/applications/models'
import { DescriptionList, DescriptionListItems } from '@/features/common/components/description-list'
Expand Down Expand Up @@ -71,23 +71,23 @@ export function DeployApp({ machine }: Props) {

const appSpec = state.context.appSpec

const asDeployCreateParams = async (
transaction: BuildTransactionResult
): Promise<(AppClientMethodCallParams & CreateOnComplete) | (AppClientBareCallParams & CreateOnComplete)> => {
const asDeployCreateParams = async (transaction: BuildTransactionResult) => {
if (transaction.type === BuildableTransactionType.MethodCall) {
const { appId: _, ...params } = await asMethodCallParams(transaction)
return {
...params,
method: params.method.name,
onComplete: params.onComplete,
} satisfies AppClientMethodCallParams & CreateOnComplete
extraProgramPages: transaction.extraProgramPages,
} satisfies AppClientMethodCallParams & CreateOnComplete & CreateSchema
} else if (transaction.type === BuildableTransactionType.AppCall) {
const { appId: _, ...params } = asAppCallTransactionParams(transaction)
invariant(params.onComplete !== algosdk.OnApplicationComplete.ClearStateOC, 'Clear state is not supported for app creates')
return {
...params,
onComplete: params.onComplete,
} satisfies AppClientBareCallParams & CreateOnComplete
extraProgramPages: transaction.extraProgramPages,
} satisfies AppClientBareCallParams & CreateOnComplete & CreateSchema
}
throw new Error('Invalid transaction type')
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ function CreateAppInterfaceInner() {

if (state.matches('createAppInterface')) {
return (
<div className={cn('relative xl:w-3/4 grid grid-cols-1 lg:grid-cols-2 gap-4')}>
<div className={cn('relative grid grid-cols-1 lg:grid-cols-2 gap-4')}>
<FromAppIdCard machine={machine} />
<FromDeploymentCard machine={machine} />
<Button type="button" variant="outline" className="mr-auto w-24" onClick={back} icon={<ArrowLeft size={16} />}>
Expand All @@ -104,13 +104,13 @@ function CreateAppInterfaceInner() {
)
} else if (state.matches('fromAppId')) {
return (
<div className="relative xl:w-3/4">
<div className="relative">
<FromAppIdWorkflow machine={machine} />
</div>
)
} else if (state.matches('fromAppDeployment')) {
return (
<div className="relative xl:w-3/4">
<div className="relative">
<FromDeploymentWorkflow machine={machine} />
</div>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import algosdk from 'algosdk'
import { bigIntSchema } from '@/features/forms/data/common'
import { bigIntSchema, numberSchema } from '@/features/forms/data/common'
import { senderFieldSchema, commonSchema, onCompleteFieldSchema, onCompleteOptions } from '@/features/transaction-wizard/data/common'
import { z } from 'zod'
import { zfd } from 'zod-form-data'
Expand All @@ -22,6 +22,7 @@ const formData = zfd.formData({
...senderFieldSchema,
...onCompleteFieldSchema,
applicationId: bigIntSchema(z.bigint({ required_error: 'Required', invalid_type_error: 'Required' })),
extraProgramPages: numberSchema(z.number().min(0).max(3).optional()),
args: zfd.repeatableOfType(
z.object({
id: z.string(),
Expand All @@ -47,11 +48,12 @@ export function AppCallTransactionBuilder({ mode, transaction, activeAccount, de
type: BuildableTransactionType.AppCall,
applicationId: Number(values.applicationId),
sender: values.sender,
onComplete: Number(values.onComplete),
extraProgramPages: values.extraProgramPages,
fee: values.fee,
validRounds: values.validRounds,
args: values.args.map((arg) => arg.value),
note: values.note,
onComplete: Number(values.onComplete),
})
},
[onSubmit, transaction?.id]
Expand All @@ -63,6 +65,7 @@ export function AppCallTransactionBuilder({ mode, transaction, activeAccount, de
applicationId: transaction.applicationId !== undefined ? BigInt(transaction.applicationId) : undefined,
sender: transaction.sender,
onComplete: transaction.onComplete.toString(),
extraProgramPages: transaction.extraProgramPages,
fee: transaction.fee,
validRounds: transaction.validRounds,
note: transaction.note,
Expand Down Expand Up @@ -116,6 +119,13 @@ export function AppCallTransactionBuilder({ mode, transaction, activeAccount, de
label: 'Sender',
helpText: 'Account to call from. Sends the transaction and pays the fee',
})}
{defaultValues.applicationId === 0n &&
helper.numberField({
field: 'extraProgramPages',
label: 'Extra program pages',
helpText:
'Number of additional pages allocated to the approval and clear state programs. If empty this will be calculated automatically',
})}
{helper.arrayField({
field: 'args',
label: 'Arguments',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import algosdk from 'algosdk'
import { bigIntSchema } from '@/features/forms/data/common'
import { bigIntSchema, numberSchema } from '@/features/forms/data/common'
import {
commonSchema,
onCompleteFieldSchema,
Expand Down Expand Up @@ -46,6 +46,7 @@ const appCallFormSchema = {
...onCompleteFieldSchema,
applicationId: bigIntSchema(z.bigint({ required_error: 'Required', invalid_type_error: 'Required' })),
methodName: zfd.text(),
extraProgramPages: numberSchema(z.number().min(0).max(3).optional()),
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const baseFormData = zfd.formData(appCallFormSchema)
Expand Down Expand Up @@ -156,6 +157,7 @@ export function MethodCallTransactionBuilder({
methodDefinition: methodDefinition,
onComplete: Number(values.onComplete),
sender: values.sender,
extraProgramPages: values.extraProgramPages,
appSpec: appSpec!,
methodArgs: methodArgs,
fee: values.fee,
Expand Down Expand Up @@ -188,6 +190,7 @@ export function MethodCallTransactionBuilder({
sender: transaction.sender,
onComplete: transaction.onComplete.toString(),
methodName: transaction.methodDefinition.name,
extraProgramPages: transaction.extraProgramPages,
fee: transaction.fee,
validRounds: transaction.validRounds,
note: transaction.note,
Expand Down Expand Up @@ -387,6 +390,13 @@ function FormInner({ helper, onAppIdChanged, onMethodNameChanged, methodDefiniti
label: 'Sender',
helpText: 'Account to call from. Sends the transaction and pays the fee',
})}
{appId === 0n &&
helper.numberField({
field: 'extraProgramPages',
label: 'Extra program pages',
helpText:
'Number of additional pages allocated to the approval and clear state programs. If empty this will be calculated automatically',
})}
{abiMethodArgs.map((arg, index) => (
<div key={`${methodName}-arg-${index}`} className="relative space-y-1.5 text-sm [&_label]:mt-1.5">
<h5 className="text-primary">{`Argument ${index + 1}`}</h5>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ const getTableColumns = ({
return (
<DescriptionList
items={asDescriptionListItems(transaction, transactionPositions, onEditTransaction)}
dtClassName="w-[9.5rem] truncate"
dtClassName="w-[10rem] truncate"
/>
)
},
Expand Down Expand Up @@ -322,7 +322,7 @@ const getSubTransactionsTableColumns = ({
) : (
<DescriptionList
items={asDescriptionListItems(transaction, transactionPositions, onEditTransaction)}
dtClassName="w-[9.5rem] truncate"
dtClassName="w-[10rem] truncate"
/>
)}
<div className="absolute -bottom-2 right-1/2 z-10">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,14 @@ const asAppCallTransaction = (transaction: BuildAppCallTransactionResult): Descr
dt: 'Sender',
dd: <AddressOrNfdLink address={params.sender} />,
},
...(transaction.extraProgramPages !== undefined
? [
{
dt: 'Extra program pages',
dd: transaction.extraProgramPages,
},
]
: []),
...(transaction.args.length > 0
? [
{
Expand Down Expand Up @@ -423,6 +431,14 @@ const asMethodCallTransaction = (
dt: 'Sender',
dd: <AddressOrNfdLink address={params.sender} />,
},
...(transaction.extraProgramPages !== undefined
? [
{
dt: 'Extra program pages',
dd: transaction.extraProgramPages,
},
]
: []),
...(transaction.methodDefinition.arguments.length > 0
? [
{
Expand Down
2 changes: 2 additions & 0 deletions src/features/transaction-wizard/models/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ type CommonBuildTransactionResult = {
export type BuildAppCallTransactionResult = CommonBuildTransactionResult & {
type: BuildableTransactionType.AppCall
applicationId: ApplicationId
extraProgramPages?: number
args: string[]
accounts?: Address[]
foreignAssets?: AssetId[]
Expand All @@ -98,6 +99,7 @@ export type BuildMethodCallTransactionResult = CommonBuildTransactionResult & {
applicationId: ApplicationId
appSpec: Arc56Contract
methodDefinition: MethodDefinition
extraProgramPages?: number
methodArgs: MethodCallArg[]
accounts?: Address[]
foreignAssets?: AssetId[]
Expand Down

0 comments on commit 4d8efe5

Please sign in to comment.