#Trying to create a child app from a parent app
61 messages ยท Page 1 of 1 (latest)
One of my favorite topics ๐ซ maybe next time
hahaha
should i just repost in the comments here?
Our automod (and one human mod) gave him a hell of a hard time
Un momento
similar to this repo:
https://github.com/algorandfoundation/beaker/tree/fb76617ea49ed26dfa98b4dbda98649731c09bdc/examples/nested_precompile/smart_contractsi am trying to create an app from an app using inner txns but i get this error when building the contracts:
Precompilation requires use of a client when calling Application.build
on this line in my contract:
escrow_app_pc = beaker.precompiled(escrow.app)found a few ppl mention similar issues:
https://algorand.struct.ai/t/error-encountered-during-contract-precompilation/2K5f82
https://algorand.struct.ai/t/error-while-creating-a-child-contract-using-beaker/2K73d6but am unsure what the actual problem is or how to fix it?
OK I have to give you the standard talking to about not using Beaker ๐
Beaker bad, use Algorand Python
i know i know ๐ข
im literally reading up on puya as we speak
but old habits die hard
I like deploying a factory, or template program, and then referencing it on app creation
interesting! can you elaborate? ๐
@abimethod
def some_method(self) -> None:
create_LP_contract = itxn.ApplicationCall(
approval_program=LP_template.approval_program,
clear_state_program=LP_template.clear_state_program,
on_completion=OnCompleteAction.NoOp,
global_num_uint=LP_template.global_num_uint,
global_num_bytes=LP_template.global_num_bytes,
fee=Global.min_txn_fee * 5,
extra_program_pages=3
).submit()
```
and then in my init I have a global state like so:
. . .
# other global states and box maps
self.poolTemplateApp = GlobalState(Application)
. . .
And I designate it with:
def designatePoolTemplateGlobal(
self,
poolTemplateApp: Application
) -> String:
assert Txn.sender == Global.creator_address
self.poolTemplateApp.value = poolTemplateApp
return String("Pool Template Designated")```
But I'm sure there are other ways too
interesting. so in my case ill need to make arbitary numbers of escrow apps.
you're suggesting i would just deploy 1 core escrow app and then use that 1 core escrow app as a refernece to create arbitrary new ones whenever i need to?
or am i misunderstanding
You could do it that way yeah, and then I like creating app boxes that store the created app IDs should I need to reference them later
You can access the created app ID in my some_method example like so:
I think the term is "factory contract" or "template contract" yeah
Regarding your Beaker error, can you share how you are calling Application.build?
interesting! apprecaite the thoughts!
let me have a think on that
Are you using an application client?
so im doing this in the parent contract:
def create_escrow(
price: pt.abi.Uint64,
quantity: pt.abi.Uint64,
slippage: pt.abi.Uint64,
position: pt.abi.Uint8,
*,
output: pt.abi.Uint8,
) -> pt.Expr:
escrow_app_pc = beaker.precompiled(escrow.app)
return pt.Seq(
pt.Assert(
pt.Txn.sender() == pt.Gtxn[pt.Txn.group_index() + pt.Int(1)].sender(),
pt.Txn.type_enum() == pt.TxnType.ApplicationCall,
pt.Gtxn[pt.Txn.group_index() + pt.Int(1)].type_enum()
== pt.TxnType.AssetTransfer,
pt.Gtxn[pt.Txn.group_index() + pt.Int(1)].asset_receiver()
== pt.Global.current_application_address(),
app.state.is_resolved.get() == pt.Int(0),
app.state.is_activated.get() == pt.Int(1),
pt.Or(
....```
and in the child contract i have this:
```app = beaker.Application("escrow_app", state=EscrowState).apply(
beaker.unconditional_create_approval, initialize_global_state=True
)```
and on this line in the parent:
`escrow_app_pc = beaker.precompiled(escrow.app)`
it says:
`Precompilation requires use of a client when calling Application.build`
and im building it with the algokit code:
def build(output_dir: Path, app: beaker.Application) -> Path:
output_dir = output_dir.resolve()
if output_dir.exists():
rmtree(output_dir)
output_dir.mkdir(exist_ok=True, parents=True)
logger.info(f"Exporting {app.name} to {output_dir}")
specification = app.build()
specification.export(output_dir)
result = subprocess.run(
[
"algokit",
"generate",
"client",
output_dir / "application.json",
"--output",
output_dir / f"client.{deployment_extension}",
],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
)
if result.returncode:
if "No such command" in result.stdout:
raise Exception(
"Could not generate typed client, requires AlgoKit 2.0.0 or "
"later. Please update AlgoKit"
)
else:
raise Exception(f"Could not generate typed client:\n{result.stdout}")
return output_dir / "application.json"
Is this Pyteal
yes ๐
๐
You can use triple backticks to format the code better
(i know im sorry)
I hung onto Pyteal for a while even though Algopy/PUYA releasedโ trust me when I say you will not regret the day you start migrating ๐ซ
i promise im going to very soon haha
i guess maybe my issue is how im building the contract? ๐ค
result = subprocess.run(
[
"algokit",
"generate",
"client",
output_dir / "application.json",
"--output",
output_dir / f"client.{deployment_extension}",
],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
)```
Have you created an application client like this anywhere?
https://github.com/algorandfoundation/beaker/tree/master?tab=readme-ov-file#hello-beaker
i do create them later in the flow after the contracts are built
tho i could create them sooner
It seems like you have to provide a client to build
The build method can accept None but if you do that, then you won't have a client to use to do the complication and itll throw this error
I think if you add the AlgodClient as an arg to specification = app.build() here, this should work
