Skip to content

Commit

Permalink
chore: Rename generate-ts/nr commands to codegen. (AztecProtocol#3843)
Browse files Browse the repository at this point in the history
* Get rid of generate-* commands on cli, in favour of `codegen` command
with optional `--ts` or `--nr` flags.
* Update docs to explain how to do a contract compilation now.
  • Loading branch information
charlielye authored Jan 5, 2024
1 parent c489727 commit 1fcb964
Show file tree
Hide file tree
Showing 10 changed files with 58 additions and 103 deletions.
2 changes: 1 addition & 1 deletion aztec-up/bin/aztec-sandbox
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ set -euo pipefail
CMD="docker compose"
$CMD &>/dev/null || CMD="docker-compose"

ARGS="-f ~/.aztec/docker-compose.yml -p sandbox"
ARGS="-f $HOME/.aztec/docker-compose.yml -p sandbox"

# Function to be executed when SIGINT is received.
cleanup() {
Expand Down
2 changes: 1 addition & 1 deletion boxes/blank-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"formatting": "prettier --check ./src && eslint ./src",
"formatting:fix": "prettier -w ./src",
"compile": "cd src/contracts && ${AZTEC_NARGO:-aztec-nargo} compile",
"codegen": "${AZTEC_CLI:-aztec-cli} generate-typescript src/contracts/target --outdir src/artifacts",
"codegen": "${AZTEC_CLI:-aztec-cli} codegen src/contracts/target -o src/artifacts --ts",
"test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --runInBand"
},
"jest": {
Expand Down
2 changes: 1 addition & 1 deletion boxes/blank/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"formatting": "prettier --check ./src && eslint ./src",
"formatting:fix": "prettier -w ./src",
"compile": "cd src/contracts && ${AZTEC_NARGO:-aztec-nargo} compile",
"codegen": "${AZTEC_CLI:-aztec-cli} generate-typescript src/contracts/target --outdir src/artifacts",
"codegen": "${AZTEC_CLI:-aztec-cli} codegen src/contracts/target -o src/artifacts --ts",
"test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --runInBand"
},
"jest": {
Expand Down
2 changes: 1 addition & 1 deletion boxes/token/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"formatting": "prettier --check ./src && eslint ./src",
"formatting:fix": "prettier -w ./src",
"compile": "cd src/contracts && ${AZTEC_NARGO:-aztec-nargo} compile",
"codegen": "${AZTEC_CLI:-aztec-cli} generate-typescript src/contracts/target --outdir src/artifacts",
"codegen": "${AZTEC_CLI:-aztec-cli} codegen src/contracts/target -o src/artifacts --ts",
"test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --runInBand"
},
"jest": {
Expand Down
48 changes: 20 additions & 28 deletions docs/docs/dev_docs/contracts/compiling.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,38 @@ In this guide we will cover how to do so, both using the CLI and programmaticall

We'll also cover how to generate a helper [TypeScript interface](#typescript-interfaces) and an [Aztec.nr interface](#noir-interfaces) for easily interacting with your contract from your typescript app and from other Aztec.nr contracts, respectively.

## Compile using the CLI
## Compile using aztec-nargo

To compile a contract using the Aztec CLI, first [install it](../cli/cli-commands#installation).
To compile a contract using the Aztec's build of nargo.

Then run the `compile` command with the path to your [contract project folder](./layout.md#directory-structure), which is the one that contains the `Nargo.toml` file:
Run the `aztec-nargo compile` command within your [contract project folder](./layout.md#directory-structure), which is the one that contains the `Nargo.toml` file:

```
aztec-cli compile ./path/to/my_aztec_contract_project
```bash
aztec-nargo compile
```

This will output a JSON [artifact](./artifacts.md) for each contract in the project to a `target` folder containing their artifact, which you can use for deploying or interacting with your contracts.
This will output a JSON [artifact](./artifacts.md) for each contract in the project to a `target` folder containing the Noir ABI artifacts.

`aztec-cli` uses `noir_wasm` by default for compiling contracts. This helps reduce the developer overhead of installation and maintaining the noir compiler, `nargo`. However, if you prefer, you can use `nargo` to compile contracts with `aztec-cli` as so:
Before you can use the ABI it currently needs to be validated as being Aztec compatible, and transformed to an Aztec compatible ABI using `aztec-cli codegen`, passing a Noir ABI file or folder, and output location, e.g:

```bash
aztec-cli compile my-contract --compiler nargo # switches compiler to nargo
aztec-cli codegen ./aztec-nargo/output/target/path -o src/artifacts
```

When you specify `nargo` as your compiler, you need to make sure that you are using the correct version. You can find the [latest version information here](../updating.md#updating-nargo).
It can be useful to perform this compilation, validation and transformation in one go, so you may wish to chain the commands and perhaps add them to a package.json script. The below assumes your contract is in a folder called `contract` at your project root:

### Typescript Interfaces

You can use the compiler to autogenerate type-safe typescript classes for each of your contracts. These classes define type-safe methods for deploying and interacting with your contract based on their artifact.
```bash
(cd contract && aztec-nargo compile && aztec-cli codegen target -o ../src/artifacts)
```

To generate them, include a `--typescript` option in the compile command with a path to the target folder for the typescript files:
### Typescript Interfaces

```
aztec-cli compile --typescript ./path/to/typescript/src ./path/to/my_aztec_contract_project
```
You can use the codegenerator to autogenerate type-safe typescript classes for each of your contracts. These classes define type-safe methods for deploying and interacting with your contract based on their artifact.

You can also generate these interfaces from prebuilt artifacts using the `generate-typescript` command:
To generate them, include a `--ts` option in the codegen command with a path to the target folder for the typescript files:

```
aztec-cli generate-typescript ./path/to/my_aztec_contract_project
```bash
aztec-cli codegen ./aztec-nargo/output/target/path -o src/artifacts --ts
```

Below is typescript code generated from the [Token](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/noir-contracts/contracts/token_contract/src/main.nr) contract:
Expand Down Expand Up @@ -133,16 +131,10 @@ An Aztec.nr contract can [call a function](./syntax/functions.md) in another con

To make this easier, the compiler can generate contract interface structs that expose a convenience method for each function listed in a given contract artifact. These structs are intended to be used from another contract project that calls into the current one. For each contract, two interface structs are generated: one to be used from private functions with a `PrivateContext`, and one to be used from open functions with a `PublicContext`.

To generate them, include a `--interface` option in the compile command with a path to the target folder for the generated Aztec.nr interface files:

```
aztec-cli compile --interface ./path/to/another_aztec_contract_project/src ./path/to/my_aztec_contract_project
```

You can also generate these interfaces from prebuilt artifacts using the `generate-noir-interface` command:
To generate them, include a `--nr` option in the `codegen` command with a path to the target folder for the generated Aztec.nr interface files:

```
aztec-cli generate-noir-interface ./path/to/my_aztec_contract_project
```bash
aztec-cli codegen ./aztec-nargo/output/target/path -o ./path/to/output/folder --nr
```

Below is an example interface, also generated from the [Token](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/noir-contracts/contracts/token_contract/src/main.nr) contract:
Expand Down
8 changes: 2 additions & 6 deletions yarn-project/cli/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import { DebugLogger, LogFn } from '@aztec/foundation/log';
import { fileURLToPath } from '@aztec/foundation/url';
import {
addGenerateNoirInterfaceCommanderAction,
addGenerateTypescriptCommanderAction,
} from '@aztec/noir-compiler/cli';
import { addCodegenCommanderAction } from '@aztec/noir-compiler/cli';

import { Command, Option } from 'commander';
import { lookup } from 'dns/promises';
Expand Down Expand Up @@ -493,8 +490,7 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
await update(projectPath, contract, rpcUrl, aztecVersion, log);
});

addGenerateTypescriptCommanderAction(program, log);
addGenerateNoirInterfaceCommanderAction(program, log);
addCodegenCommanderAction(program, log);

return program;
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ interface Options {
*
*/
export function addNoirCompilerCommanderActions(program: Command, log: LogFn = () => {}) {
// addCompileCommanderAction(program, log);
addGenerateTypescriptCommanderAction(program, log);
addGenerateNoirInterfaceCommanderAction(program, log);
addCodegenCommanderAction(program, log);
}

/**
Expand All @@ -48,30 +46,20 @@ export function addCompileCommanderAction(program: Command, log: LogFn = () => {
/**
*
*/
export function addGenerateTypescriptCommanderAction(program: Command, _: LogFn = () => {}) {
export function addCodegenCommanderAction(program: Command, _: LogFn = () => {}) {
program
.command('generate-typescript')
.command('codegen')
.argument('<noir-abi-path>', 'Path to the Noir ABI or project dir.')
.option('-o, --outdir <path>', 'Output folder for the generated typescript.')
.option('-o, --outdir <path>', 'Output folder for the generated code.')
.option('-d, --debug', 'Include debug info.')
.description('Generates TypeScript interface from the given abi.')
.action(async (noirAbiPath: string, { debug, outdir }) => {
const { generateTypescriptInterface } = await import('./generate_typescript_interface.js');
generateTypescriptInterface(outdir || dirname(noirAbiPath), noirAbiPath, debug);
});
}

/**
*
*/
export function addGenerateNoirInterfaceCommanderAction(program: Command, _: LogFn = () => {}) {
return program
.command('generate-noir-interface')
.argument('<noir-abi-path>', 'Path to the Noir ABI or project dir.')
.option('-o, --outdir <path>', 'Output folder for the generated noir.')
.description('Generates Noir interfaces from the artifacts in the given project')
.action(async (noirAbiPath: string, { outdir }) => {
const { generateNoirInterface } = await import('./generate_noir_interface.js');
generateNoirInterface(outdir || dirname(noirAbiPath), noirAbiPath);
.option('--ts', 'Generate TypeScript wrapper.')
.option('--nr', 'Generate Noir interface.')
.description('Validates and generates an Aztec Contract ABI from Noir ABI.')
.action(async (noirAbiPath: string, { debug, outdir, ts, nr }) => {
if (ts && nr) {
throw new Error('--ts and --nr are mutually exclusive.');
}
const { generateCode } = await import('./codegen.js');
generateCode(outdir || dirname(noirAbiPath), noirAbiPath, debug, ts, nr);
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,48 @@ import path from 'path';

import { generateContractArtifact } from '../contract-interface-gen/abi.js';
import { generateTypescriptContractInterface } from '../contract-interface-gen/contractTypescript.js';
import { generateNoirContractInterface } from '../contract-interface-gen/noir.js';

/**
*
*/
export function generateTypescriptInterface(outputPath: string, fileOrDirPath: string, includeDebug = false) {
export function generateCode(outputPath: string, fileOrDirPath: string, includeDebug = false, ts = false, nr = false) {
const stats = statSync(fileOrDirPath);

if (stats.isDirectory()) {
const files = readdirSync(fileOrDirPath).filter(file => file.endsWith('.json') && !file.startsWith('debug_'));
for (const file of files) {
const fullPath = path.join(fileOrDirPath, file);
generateTypescriptInterfaceFromNoirAbi(outputPath, fullPath, includeDebug);
generateFromNoirAbi(outputPath, fullPath, includeDebug, ts, nr);
}
} else if (stats.isFile()) {
generateTypescriptInterfaceFromNoirAbi(outputPath, fileOrDirPath, includeDebug);
generateFromNoirAbi(outputPath, fileOrDirPath, includeDebug, ts, nr);
}
}

/**
*
*/
function generateTypescriptInterfaceFromNoirAbi(outputPath: string, noirAbiPath: string, includeDebug: boolean) {
function generateFromNoirAbi(outputPath: string, noirAbiPath: string, includeDebug: boolean, ts: boolean, nr: boolean) {
const contract = JSON.parse(readFileSync(noirAbiPath, 'utf8'));
const noirDebugPath = includeDebug ? getDebugFilePath(noirAbiPath) : undefined;
const debug = noirDebugPath ? JSON.parse(readFileSync(noirDebugPath, 'utf8')) : undefined;
const aztecAbi = generateContractArtifact({ contract, debug });
const tsWrapper = generateTypescriptContractInterface(aztecAbi, `./${aztecAbi.name}.json`);

mkdirSync(outputPath, { recursive: true });
writeFileSync(`${outputPath}/${aztecAbi.name}.ts`, tsWrapper);

if (nr) {
const noirContract = generateNoirContractInterface(aztecAbi);
writeFileSync(`${outputPath}/${aztecAbi.name}.nr`, noirContract);
return;
}

writeFileSync(`${outputPath}/${aztecAbi.name}.json`, JSON.stringify(aztecAbi, undefined, 2));

if (ts) {
const tsWrapper = generateTypescriptContractInterface(aztecAbi, `./${aztecAbi.name}.json`);
writeFileSync(`${outputPath}/${aztecAbi.name}.ts`, tsWrapper);
}
}

/**
Expand Down
33 changes: 0 additions & 33 deletions yarn-project/noir-compiler/src/cli/generate_noir_interface.ts

This file was deleted.

2 changes: 1 addition & 1 deletion yarn-project/noir-contracts/scripts/generate-types.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ for ABI in $(find target -maxdepth 1 -type f ! -name 'debug_*' -name '*.json');
DEBUG_INFO="$(dirname $ABI)/debug_$(basename $ABI)"

echo "Creating types for $CONTRACT in $ABI..."
node --no-warnings ../noir-compiler/dest/cli.js generate-typescript -o $OUT_DIR -d $ABI
node --no-warnings ../noir-compiler/dest/cli.js codegen -o $OUT_DIR -d --ts $ABI

# Add contract import/export to index.ts.
echo "export * from './${CONTRACT}.js';" >> $INDEX
Expand Down

0 comments on commit 1fcb964

Please sign in to comment.