import { UTest } from 'atma-utest'; import { Web3ClientFactory } from 'dequanto/clients/Web3ClientFactory'; import { Deployments } from 'dequanto/contracts/deploy/Deployments'; import { Generator } from 'dequanto/gen/Generator'; import { $account } from 'dequanto/utils/$account'; import { $require } from 'dequanto/utils/$require'; import { File } from 'atma-io'; // In a Hardhat project, include the @0xweb/hardhat plugin in hardhat.config.*. // See https://github.com/0xweb-org/hardhat for plugin setup. // Then hardhat compile auto-generates contract classes in 0xc/hardhat/**. // A deployment script can import the generated class directly: // import { FooContract } from '0xc/hardhat/FooContract/FooContract'; declare const include: any; UTest.create({ async 'deploy a generated contract class with Deployments.ensure' () { const { client, deployer, FooContract } = await getContractClass(); const deployments = new Deployments(client, deployer, { directory: './test/tmp/ai-examples/' }); // ensure returns an existing deployment by contract name, or by DeploymentOptions.id when provided. // On mainnet, new deployments are automatically verified on the configured block explorer. const { contract } = await deployments.ensure(FooContract, { arguments: [] }); // With an imported autogenerated class, contract is typed as FooContract with typed read/write methods. const value = await (contract as any).getValue(); $require.AddressNotEmpty(contract.address); $require.eq(value, 4n); }, async 'deploy a generated contract class with an upgradeable proxy' () { const { client, deployer, FooContract } = await getContractClass(); const deployments = new Deployments(client, deployer, { directory: './test/tmp/ai-examples/' }); // ensureWithProxy uses OpenZeppelin TransparentUpgradeableProxy by default. // It tracks Proxy, ProxyAdmin, and implementation deployments separately. // The implementation bytecode hash is saved, so Solidity source changes deploy a new implementation. // Existing proxies are then upgraded with upgradeToAndCall; the deployment call stays almost the same. const { contract } = await deployments.ensureWithProxy(FooContract, { arguments: [], initialize: [] }); // With an imported autogenerated class, contract is typed as FooContract with typed read/write methods. const value = await (contract as any).getValue(); $require.AddressNotEmpty(contract.address); $require.eq(value, 6n); } }); async function getContractClass () { const client = await Web3ClientFactory.getAsync('hh:memory'); const deployer = $account.generate('deployer'); await client.debug.setBalance(deployer.address, BigInt(1e18)); // Test-only cleanup: real projects usually keep deployment records between runs. const deploymentsFile = './test/tmp/ai-examples/deployments-hardhat.json'; await File.removeAsync(deploymentsFile); // Test-only generation/loading: hardhat compile normally generates this class via @0xweb/hardhat. const generated = await Generator.generateFromSol('./test/fixtures/deployments/DeploymentsFoo.sol'); const module = await include.instance().js(generated.main); const FooContract = module.DeploymentsFoo.DeploymentsFoo; return { client, deployer, FooContract }; }