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

feat: aztec-cli unbox "really empty box" #2388

Merged
merged 21 commits into from
Sep 19, 2023
Merged
Show file tree
Hide file tree
Changes from 8 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
60 changes: 60 additions & 0 deletions yarn-project/boxes/blank/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react-hooks/recommended',
dan-aztec marked this conversation as resolved.
Show resolved Hide resolved
'plugin:import/recommended',
'plugin:import/typescript',
'prettier',
],
settings: {
'import/resolver': {
typescript: true,
node: true,
},
},
ignorePatterns: ['dist', '.eslintrc.cjs'],
parser: '@typescript-eslint/parser',
plugins: ['react-refresh'],
overrides: [
{
files: ['*.ts', '*.tsx'],
parserOptions: {
// hacky workaround for CI not having the same tsconfig setup
project: true,
},
},
],
rules: {
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/await-thenable': 'error',
'@typescript-eslint/no-floating-promises': 2,
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
'require-await': 2,
'no-console': 'warn',
'no-constant-condition': 'off',
camelcase: 2,
'no-restricted-imports': [
'error',
{
patterns: [
{
group: ['client-dest'],
message: "Fix this absolute garbage import. It's your duty to solve it before it spreads.",
},
{
group: ['dest'],
message: 'You should not be importing from a build directory. Did you accidentally do a relative import?',
},
],
},
],
'import/no-unresolved': 'error',
'import/no-extraneous-dependencies': 'error',
},
};
24 changes: 24 additions & 0 deletions yarn-project/boxes/blank/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dan-aztec marked this conversation as resolved.
Show resolved Hide resolved
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
6 changes: 6 additions & 0 deletions yarn-project/boxes/blank/.prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"singleQuote": true,
"trailingComma": "all",
"printWidth": 120,
"arrowParens": "avoid"
}
89 changes: 89 additions & 0 deletions yarn-project/boxes/blank/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
This is a minimal [Aztec](https://aztec.network/) Noir smart contract and frontend bootstrapped with [`aztec-cli unbox`](https://github.com/AztecProtocol/aztec-packages/tree/master/yarn-project/cli). It is recommended you use the `aztec-cli unbox blank` command so that the repository is copied with needed modifications from the monorepo subpackage.

## Setup

Dependencies can be installed from the root of the package:

```bash
yarn
yarn install:noir
yarn install:sandbox
yarn build
```

In addition to the usual javascript dependencies, this project requires `nargo` (package manager) and `noir` (Aztec ZK smart contract language) in addition to `@aztec/aztec-cli`.

The former are installed within `yarn install:noir` which executes

```bash
curl -L https://raw.githubusercontent.com/noir-lang/noirup/main/install | bash

noirup -v aztec
```

This sandbox requires [Docker](https://www.docker.com/) to be installed _and running_ locally. In the event the image needs updating, you can run `yarn install:sandbox` which executes

```bash
docker pull aztecprotocol/aztec-sandbox:latest
```
dan-aztec marked this conversation as resolved.
Show resolved Hide resolved

## Getting started

After `yarn build` has run,`yarn start:sandbox` in one terminal will launch a local instance of the Aztec sandbox via Docker Compose and `yarn start:dev` will launch a frontend app for deploying and interacting with the PrivateToken contract.
dan-aztec marked this conversation as resolved.
Show resolved Hide resolved

At this point, [http://localhost:5173](http://localhost:5173) should provide a minimal smart contract frontend.

This folder should have the following directory structure:

```
|— README.md
|— package.json
|— src
index.html
index.ts
|— contracts
|— src
| The Noir smart contract source files are here.
|— main.nr - the cloned noir contract, your starting point
|- interface.nr - autogenerated from main.nr when you compile
|— Nargo.toml [Noir build file, includes Aztec smart contract dependencies]
|— artifacts
| These are both generated from `contracts/` by the compile command
|— private_token_contract.json
|— private_token.ts
|— tests
| A simple end2end test deploying and testing the minimal contract on a local sandbox
| using the front end helper methods in index.ts
| The test requires the sandbox and anvil to be running (yarn start:sandbox).
|- test.frontennd.test.ts
```

Most relevant to you is likely `src/contracts/main.nr` (and the build config `src/contracts/Nargo.toml`). This contains the example blank contract logic that the frontend interacts with and is a good place to start writing Noir.

The `src/artifacts` folder can be re-generated from the command line with `yarn compile` which is an alias for

```bash
aztec-cli compile src/contracts --outdir ../artifacts --typescript ../artifacts
dan-aztec marked this conversation as resolved.
Show resolved Hide resolved
```

This will generate a [Contract ABI](https://www.alchemy.com/overviews/what-is-an-abi-of-a-smart-contract-examples-and-usage) and TypeScript class for the Aztec smart contract in `src/contracts/main.nr`, which the frontend uses to generate the UI.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Wrong link.


Note: the `compile` command seems to generate a Typescript file which needs a single change -
Copy link
Collaborator

Choose a reason for hiding this comment

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

If this is true, we should open an issue and fix the command so that the path can be correctly generated.


```
import TestContractAbiJson from 'text_contract.json' assert { type: 'json' };
// need to update the relative import to
import TestContractAbiJson from './test_contract.json' assert { type: 'json' };
```

After compiling, you can re-deploy the upated noir smart contract from the web UI. The function interaction forms are generated from parsing the ContractABI, so they should update automatically after you recompile.

## Learn More

To learn more about Noir Smart Contract development, take a look at the following resources:

- [Awesome Noir](https://github.com/noir-lang/awesome-noir) - learn about the Noir programming language.

## Deploy on Aztec3

Coming Soon :)
89 changes: 89 additions & 0 deletions yarn-project/boxes/blank/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
{
"name": "blank-contract",
"private": true,
"version": "0.1.0",
"type": "module",
"main": "./dest/index.js",
"scripts": {
"build": "yarn clean && webpack",
"install:noir": "curl -L https://raw.githubusercontent.com/noir-lang/noirup/main/install | bash noirup -v aztec",
"install:sandbox": "docker pull aztecprotocol/aztec-sandbox:latest",
"clean": "rm -rf ./dest .tsbuildinfo",
"start": "serve -p 3000 ./dest",
"start:dev": "webpack serve --mode=development",
"start:sandbox": "SANDBOX_VERSION=latest /bin/bash -c \"$(curl -fsSL 'https://sandbox.aztec.network')\" ",
"formatting": "prettier --check ./src && eslint ./src",
"formatting:fix": "prettier -w ./src",
"compile": "aztec-cli compile src/contracts --outdir ../artifacts --typescript ../artifacts",
"test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --runInBand",
"test:integration": "concurrently -k -s first -c reset,dim -n test,anvil \"yarn test\" \"anvil\""
},
"jest": {
"preset": "ts-jest'",
"testEnvironment": "jsdom"
},
"dependencies": {
"@aztec/aztec-ui": "^0.1.14",
"@aztec/aztec.js": "workspace:^",
"@aztec/circuits.js": "workspace:^",
"@aztec/cli": "workspace:^",
"@aztec/foundation": "workspace:^",
"classnames": "^2.3.2",
"formik": "^2.4.3",
dan-aztec marked this conversation as resolved.
Show resolved Hide resolved
"node-sass": "^9.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"sass-loader": "^13.3.2",
"serve": "^14.2.1",
"yup": "^1.2.0"
},
"devDependencies": {
"@types/node": "^20.5.9",
"@types/react": "^18.2.15",
"@types/react-dom": "^18.2.7",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"autoprefixer": "^10.4.15",
"copy-webpack-plugin": "^11.0.0",
"css-loader": "^6.8.1",
"eslint": "^8.45.0",
"eslint-import-resolver-typescript": "^3.5.5",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.3",
"jest": "^29.6.4",
"postcss": "^8.4.29",
"postcss-loader": "^7.3.3",
"prettier": "^3.0.3",
"resolve-typescript-plugin": "^2.0.1",
"stream-browserify": "^3.0.0",
"style-loader": "^3.3.3",
"ts-jest": "^29.1.1",
"ts-loader": "^9.4.4",
"ts-node": "^10.9.1",
"tty-browserify": "^0.0.1",
"typescript": "^5.0.4",
"util": "^0.12.5",
"webpack": "^5.88.2",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.15.1"
},
"browserslist": {
"production": [
">0.5%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"files": [
"dest",
"src",
"!*.test.*"
],
"types": "./dest/index.d.ts"
}
4 changes: 4 additions & 0 deletions yarn-project/boxes/blank/src/@types/index.d.ts
dan-aztec marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
declare module '*.svg' {
const content: any;
export default content;
}
80 changes: 80 additions & 0 deletions yarn-project/boxes/blank/src/artifacts/test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/* Autogenerated file, do not edit! */

/* eslint-disable */
import {
AztecAddress,
CompleteAddress,
ContractBase,
ContractFunctionInteraction,
ContractMethod,
DeployMethod,
FieldLike,
Wallet,
} from '@aztec/aztec.js';
import { ContractAbi } from '@aztec/foundation/abi';
import { Point } from '@aztec/foundation/fields';
import { AztecRPC, PublicKey } from '@aztec/types';

import TestContractAbiJson from './test_contract.json' assert { type: 'json' };

export const TestContractAbi = TestContractAbiJson as ContractAbi;

/**
* Type-safe interface for contract Test;
*/
export class TestContract extends ContractBase {
private constructor(
/** The deployed contract's complete address. */
completeAddress: CompleteAddress,
/** The wallet. */
wallet: Wallet,
) {
super(completeAddress, TestContractAbi, wallet);
}

/**
* Creates a contract instance.
* @param address - The deployed contract's address.
* @param wallet - The wallet to use when interacting with the contract.
* @returns A promise that resolves to a new Contract instance.
*/
public static async at(
/** The deployed contract's address. */
address: AztecAddress,
/** The wallet. */
wallet: Wallet,
) {
const extendedContractData = await wallet.getExtendedContractData(address);
if (extendedContractData === undefined) {
throw new Error('Contract ' + address.toString() + ' is not deployed');
}
return new TestContract(extendedContractData.getCompleteAddress(), wallet);
}

/**
* Creates a tx to deploy a new instance of this contract.
*/
public static deploy(rpc: AztecRPC) {
return new DeployMethod<TestContract>(Point.ZERO, rpc, TestContractAbi, Array.from(arguments).slice(1));
}

/**
* Creates a tx to deploy a new instance of this contract using the specified public key to derive the address.
*/
public static deployWithPublicKey(rpc: AztecRPC, publicKey: PublicKey) {
return new DeployMethod<TestContract>(publicKey, rpc, TestContractAbi, Array.from(arguments).slice(2));
}

/**
* Returns this contract's ABI.
*/
public static get abi(): ContractAbi {
return TestContractAbi;
}

/** Type-safe wrappers for the public methods exposed by the contract. */
public methods!: {
/** getPublicKey(address: field) */
getPublicKey: ((address: FieldLike) => ContractFunctionInteraction) & Pick<ContractMethod, 'selector'>;
};
}
Loading