Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions yarn-project/cli-wallet/src/bin/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Fr, computeSecretHash, fileURLToPath } from '@aztec/aztec.js';
import { Fr, computeSecretHash, createCompatibleClient, fileURLToPath } from '@aztec/aztec.js';
import { LOCALHOST } from '@aztec/cli/cli-utils';
import { type LogFn, createConsoleLogger, createLogger } from '@aztec/foundation/log';
import { openStoreAt } from '@aztec/kv-store/lmdb-v2';
Expand Down Expand Up @@ -90,7 +90,7 @@ async function main() {
.default(`http://${LOCALHOST}:8080`),
)
.hook('preSubcommand', async command => {
const { dataDir, remotePxe, nodeUrl, prover } = command.optsWithGlobals();
const { dataDir, remotePxe, nodeUrl, prover, rpcUrl } = command.optsWithGlobals();

if (!remotePxe) {
debugLogger.info('Using local PXE service');
Expand All @@ -113,6 +113,25 @@ async function main() {
await pxeWrapper.init(nodeUrl, join(dataDir, 'pxe'), overridePXEConfig);
}
await db.init(await openStoreAt(dataDir));
let protocolContractsRegistered;
try {
protocolContractsRegistered = !!(await db.retrieveAlias('contracts:classRegisterer'));
// eslint-disable-next-line no-empty
} catch {}
if (!protocolContractsRegistered) {
userLog('Registering protocol contract aliases...');
const client = pxeWrapper?.getPXE() ?? (await createCompatibleClient(rpcUrl, debugLogger));
const { protocolContractAddresses } = await client.getPXEInfo();
for (const [name, address] of Object.entries(protocolContractAddresses)) {
await db.storeAlias('contracts', name, Buffer.from(address.toString()), userLog);
await db.storeAlias(
'artifacts',
address.toString(),
Buffer.from(`${name.slice(0, 1).toUpperCase()}${name.slice(1)}`),
userLog,
);
}
}
});

injectCommands(program, userLog, debugLogger, db, pxeWrapper);
Expand Down
6 changes: 3 additions & 3 deletions yarn-project/cli-wallet/src/cmds/deploy.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { type AccountWalletWithSecretKey, ContractDeployer, type DeployOptions, Fr, type PXE } from '@aztec/aztec.js';
import { encodeArgs, getContractArtifact } from '@aztec/cli/utils';
import type { LogFn, Logger } from '@aztec/foundation/log';
import { getInitializer } from '@aztec/stdlib/abi';
import { getAllFunctionAbis, getInitializer } from '@aztec/stdlib/abi';
import { PublicKeys } from '@aztec/stdlib/keys';

import { type IFeeOpts, printGasEstimates } from '../utils/options/fees.js';

export async function deploy(
client: PXE,
wallet: AccountWalletWithSecretKey,
artifactPath: string,
json: boolean,
Expand All @@ -27,7 +26,8 @@ export async function deploy(
) {
salt ??= Fr.random();
const contractArtifact = await getContractArtifact(artifactPath, log);
const constructorArtifact = getInitializer(contractArtifact, initializer);
const hasInitializer = getAllFunctionAbis(contractArtifact).some(fn => fn.isInitializer);
const constructorArtifact = hasInitializer ? getInitializer(contractArtifact, initializer) : undefined;

// TODO(#12081): Add contractArtifact.noirVersion and check here (via Noir.lock)?

Expand Down
41 changes: 38 additions & 3 deletions yarn-project/cli-wallet/src/cmds/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,6 @@ export function injectCommands(
debugLogger.info(`Using wallet with address ${wallet.getCompleteAddress().address.toString()}`);

const address = await deploy(
client,
wallet,
artifactPath,
json,
Expand Down Expand Up @@ -639,21 +638,57 @@ export function injectCommands(
aliasedAddressParser('accounts', address, db),
)
.argument('[artifact]', ARTIFACT_DESCRIPTION, artifactPathParser)
.option('--init <string>', 'The contract initializer function to call', 'constructor')
.option(
'-k, --public-key <string>',
'Optional encryption public key for this address. Set this value only if this contract is expected to receive private notes, which will be encrypted using this public key.',
parsePublicKey,
)
.option(
'-s, --salt <hex string>',
'Optional deployment salt as a hex string for generating the deployment address.',
parseFieldFromHexString,
)
.option('--deployer <string>', 'The address of the account that deployed the contract', address =>
aliasedAddressParser('accounts', address, db),
)
.addOption(createArgsOption(true, db))
.addOption(pxeOption)
.addOption(createAccountOption('Alias or address of the account to simulate from', !db, db))
.addOption(createAliasOption('Alias for the contact. Used for easy reference in subsequent commands.', !db))
.action(async (address, artifactPathPromise, _options, command) => {
const { registerContract } = await import('./register_contract.js');
const { from: parsedFromAddress, rpcUrl, nodeUrl, secretKey, alias } = command.optsWithGlobals();
const {
from: parsedFromAddress,
rpcUrl,
nodeUrl,
secretKey,
alias,
init,
publicKey,
salt,
deployer,
args,
} = command.optsWithGlobals();
const client = pxeWrapper?.getPXE() ?? (await createCompatibleClient(rpcUrl, debugLogger));
const node = pxeWrapper?.getNode() ?? createAztecNodeClient(nodeUrl);
const account = await createOrRetrieveAccount(client, parsedFromAddress, db, secretKey);
const wallet = await account.getWallet();

const artifactPath = await artifactPathPromise;

const instance = await registerContract(wallet, node, address, artifactPath, log);
const instance = await registerContract(
wallet,
node,
address,
artifactPath,
log,
init,
publicKey,
args,
salt,
deployer,
);

if (db && alias) {
await db.storeContract(instance.address, artifactPath, log, alias);
Expand Down
33 changes: 29 additions & 4 deletions yarn-project/cli-wallet/src/cmds/register_contract.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,43 @@
import type { AccountWalletWithSecretKey, AztecAddress, AztecNode } from '@aztec/aztec.js';
import {
type AccountWalletWithSecretKey,
type AztecAddress,
type AztecNode,
type Fr,
PublicKeys,
getContractInstanceFromDeployParams,
} from '@aztec/aztec.js';
import { getContractArtifact } from '@aztec/cli/cli-utils';
import type { LogFn } from '@aztec/foundation/log';
import { type LogFn } from '@aztec/foundation/log';
import { getAllFunctionAbis, getInitializer } from '@aztec/stdlib/abi';

export async function registerContract(
wallet: AccountWalletWithSecretKey,
node: AztecNode,
address: AztecAddress,
artifactPath: string,
log: LogFn,
initializer?: string,
publicKeys?: PublicKeys,
rawArgs?: any[],
salt?: Fr,
deployer?: AztecAddress | undefined,
) {
const contractArtifact = await getContractArtifact(artifactPath, log);
const contractInstance = await node.getContract(address);
const hasInitializer = getAllFunctionAbis(contractArtifact).some(fn => fn.isInitializer);
const constructorArtifact = hasInitializer ? getInitializer(contractArtifact, initializer) : undefined;
let contractInstance = await node.getContract(address);
if (!contractInstance) {
throw new Error(`Contract not found at address: ${address}`);
log(`Contract not found in the node at ${address}. Computing instance locally...`);
contractInstance = await getContractInstanceFromDeployParams(contractArtifact, {
constructorArtifact,
publicKeys: publicKeys ?? PublicKeys.default(),
constructorArgs: rawArgs,
salt,
deployer,
});
}
if (!contractInstance.address.equals(address)) {
throw new Error(`Contract address mismatch: expected ${address}, got ${contractInstance.address}`);
}
await wallet.registerContract({ instance: contractInstance, artifact: contractArtifact });
log(`Contract registered: at ${contractInstance.address}`);
Expand Down
Loading