Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Rename generate-ts/nr commands to codegen. #3843

Merged
merged 4 commits into from
Jan 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
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;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return;

Unless we want to prevent running --nr and --ts simultaneously for some reason

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, if specify --nr, you dont want the transformed json abi being output.
basically,

  • no flag = abi (to be deprecated)
  • --ts = abi + ts interface (to eventually become just ts interface)
  • --nr = just nr interface

Copy link
Collaborator

@spalladino spalladino Jan 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understand why you wouldn't want the abi being output if you run --nr, but if we do, we should at least throw or warn if the user has set both --nr and --ts. Otherwise, the cli will just output the nr without any indication to the user.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps i should have left them as distinct commands actually, as the two languages are mutually exclusive.

}

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
Loading