Skip to content

Commit 3d08ef9

Browse files
authored
chore: Just nargo compile. (AztecProtocol#3775)
Ok. Don't be scared. 262 files sounds horrific but it's mostly path updates and that kind of nonsense. The `noir-contracts` and `noir-compiler` changes are probably what to focus on. * We update boxes to use our build of nargo, and the modified code-generator. * We update paths in docs, as noir-contracts/src/contracts moved to noir-contracts/contracts, as src is now pure codegen output. * Contracts are now imported e.g. `import { ChildContractArtifact } from '@aztec/noir-contracts/Child';`. You can still just import from top level index, but it's pretty cruel to ask the runtime to parse all the artifacts just to get one, they are huge. * Contract files are now just named as per the name of the contract (i.e. not snake case). Less moving parts is better here. Given it's codegen output it's acceptable to allow the output names to be inconsistent. * aztec.js is now responsible for copying the account contracts into itself, as opposed to have some other random module push code into it. But we just need to get rid of this baked account stuff at some point anyway. * Got rid of lodash.zip in one place, and then restrained myself to not go further. But think we should remove the "trivial" lodash cases at some point. * Tidied up yp/bootstrap a bit, it's basically in line with the dockerfile at this point. Will prob make dockerfile just call bootstrap as part of some other docker cleanup I'll do later. * `source-map-support` in cli. * Remove compile command from cli. We are just going to promote use of aztec-nargo. * The ts and noir generators now expect nargo output as input, rather than our transformed abi. The ts generator outputs the transformed abi as part of it's generation. * Delete all the script stuff from `noir-contracts`. src folder is now just the codegen output, and the codegen is done with a trivial script to call compile and the ts generator in noir-compiler. * Added an unused script called `transform_json_abi.sh` that uses a tiny bit of jq to perform the transform. Probably to be deleted, especially if we just stop transforming the noir output and use it directly, but it served me as a useful tool at one point.
1 parent c58b197 commit 3d08ef9

File tree

262 files changed

+902
-1485
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

262 files changed

+902
-1485
lines changed

aztec-up/bin/aztec-up

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#!/usr/bin/env bash
22
set -euo pipefail
33

4+
export VERSION=${1:-$VERSION}
45
export SKIP_TITLE=1
5-
bash -i <(curl -s http://install.aztec.network)
6+
bash -i <(curl -s http://install.aztec.network)

boxes/Dockerfile

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
# Builds the boxes (they were copied into yarn-project-base so the cli can unbox).
22
# Produces a container that can be run to test a specific box. See docker-compose.yml.
33
FROM 278380418400.dkr.ecr.eu-west-2.amazonaws.com/aztec-sandbox AS aztec-sandbox
4+
FROM 278380418400.dkr.ecr.eu-west-2.amazonaws.com/noir as noir
45

56
# We need yarn. Start fresh container.
67
FROM node:18.19.0
78
COPY --from=aztec-sandbox /usr/src /usr/src
9+
COPY --from=noir /usr/src/noir/target/release/nargo /usr/src/noir/target/release/nargo
810
WORKDIR /usr/src/boxes
9-
ENV AZTEC_CLI=../../yarn-project/cli/aztec-cli-dest
11+
ENV AZTEC_NARGO=/usr/src/noir/target/release/nargo
12+
ENV AZTEC_CLI=/usr/src/yarn-project/cli/aztec-cli-dest
1013
RUN yarn && yarn build
11-
ENTRYPOINT ["yarn", "workspace"]
14+
ENTRYPOINT ["yarn", "workspace"]

boxes/blank-react/package.json

+4-3
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@
55
"type": "module",
66
"main": "./dest/index.js",
77
"scripts": {
8-
"build": "yarn clean && yarn compile && tsc -b && webpack",
9-
"clean": "rm -rf ./dest .tsbuildinfo",
8+
"build": "yarn clean && yarn compile && yarn codegen && tsc -b && webpack",
9+
"clean": "rm -rf ./dest .tsbuildinfo ./src/artifacts ./src/contracts/target",
1010
"start": "serve -p 3000 ./dest",
1111
"start:dev": "webpack serve --mode=development",
1212
"formatting": "prettier --check ./src && eslint ./src",
1313
"formatting:fix": "prettier -w ./src",
14-
"compile": "${AZTEC_CLI:-aztec-cli} compile src/contracts --outdir ../artifacts --typescript ../artifacts",
14+
"compile": "cd src/contracts && ${AZTEC_NARGO:-aztec-nargo} compile",
15+
"codegen": "${AZTEC_CLI:-aztec-cli} generate-typescript src/contracts/target --outdir src/artifacts",
1516
"test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --runInBand"
1617
},
1718
"jest": {

boxes/blank-react/tsconfig.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,5 @@
2121
"skipLibCheck": true,
2222
"jsx": "react-jsx"
2323
},
24-
"include": ["src", "src/**/*.json"]
24+
"include": ["src", "src/artifacts/Blank.json"]
2525
}

boxes/blank/package.json

+4-3
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@
55
"type": "module",
66
"main": "./dest/index.js",
77
"scripts": {
8-
"build": "yarn clean && yarn compile && tsc -b && webpack",
9-
"clean": "rm -rf ./dest .tsbuildinfo",
8+
"build": "yarn clean && yarn compile && yarn codegen && tsc -b && webpack",
9+
"clean": "rm -rf ./dest .tsbuildinfo ./src/artifacts ./src/contracts/target",
1010
"start": "serve -p 3000 ./dest",
1111
"start:dev": "webpack serve --mode=development",
1212
"formatting": "prettier --check ./src && eslint ./src",
1313
"formatting:fix": "prettier -w ./src",
14-
"compile": "${AZTEC_CLI:-aztec-cli} compile src/contracts --outdir ../artifacts --typescript ../artifacts",
14+
"compile": "cd src/contracts && ${AZTEC_NARGO:-aztec-nargo} compile",
15+
"codegen": "${AZTEC_CLI:-aztec-cli} generate-typescript src/contracts/target --outdir src/artifacts",
1516
"test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --runInBand"
1617
},
1718
"jest": {

boxes/blank/tsconfig.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,5 @@
2121
"skipLibCheck": true,
2222
"jsx": "react-jsx"
2323
},
24-
"include": ["src", "src/**/*.json"]
24+
"include": ["src", "src/artifacts/Blank.json"]
2525
}

boxes/token/package.json

+4-3
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@
55
"type": "module",
66
"main": "./dest/index.js",
77
"scripts": {
8-
"build": "yarn clean && yarn compile && tsc -b && webpack",
9-
"clean": "rm -rf ./dest .tsbuildinfo",
8+
"build": "yarn clean && yarn compile && yarn codegen && tsc -b && webpack",
9+
"clean": "rm -rf ./dest .tsbuildinfo ./src/artifacts ./src/contracts/target",
1010
"start": "serve -p 3000 ./dest",
1111
"start:dev": "webpack serve --mode=development",
1212
"formatting": "prettier --check ./src && eslint ./src",
1313
"formatting:fix": "prettier -w ./src",
14-
"compile": "${AZTEC_CLI:-aztec-cli} compile src/contracts --outdir ../artifacts --typescript ../artifacts",
14+
"compile": "cd src/contracts && ${AZTEC_NARGO:-aztec-nargo} compile",
15+
"codegen": "${AZTEC_CLI:-aztec-cli} generate-typescript src/contracts/target --outdir src/artifacts",
1516
"test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --runInBand"
1617
},
1718
"jest": {

boxes/token/tsconfig.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,5 @@
2121
"skipLibCheck": true,
2222
"jsx": "react-jsx"
2323
},
24-
"include": ["src", "src/**/*.json"]
24+
"include": ["src", "src/artifacts/Token.json"]
2525
}

build_manifest.yml

+1
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ boxes:
166166
buildDir: boxes
167167
dependencies:
168168
- aztec-sandbox
169+
- noir
169170
runDependencies:
170171
- aztec-sandbox
171172

docs/docs/concepts/foundation/accounts/keys.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Since Aztec implements full [signature abstraction](./main.md), signing keys dep
1212

1313
This is a snippet of our Schnorr Account contract implementation, which uses Schnorr signatures for authentication:
1414

15-
#include_code entrypoint /yarn-project/noir-contracts/src/contracts/schnorr_account_contract/src/main.nr rust
15+
#include_code entrypoint /yarn-project/noir-contracts/contracts/schnorr_account_contract/src/main.nr rust
1616

1717
Still, different accounts may use different signing schemes, may require multi-factor authentication, or _may not even use signing keys_ and instead rely on other authentication mechanisms. Read [how to write an account contract](../../../dev_docs/wallets/writing_an_account_contract.md) for a full example of how to manage authentication.
1818

docs/docs/dev_docs/cli/cli-commands.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ export ADDRESS2=<Account address printed by the above command>
9393

9494
## Deploying a Token Contract
9595

96-
We will now deploy a token contract using the `deploy` command, and set an address of the admin via a constructor argument. You can find the contract we are deploying [here](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/noir-contracts/src/contracts/token_contract/src/main.nr) (or write it for yourself in [this tutorial!](../tutorials/writing_token_contract.md))
96+
We will now deploy a token contract using the `deploy` command, and set an address of the admin via a constructor argument. You can find the contract we are deploying [here](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/noir-contracts/contracts/token_contract/src/main.nr) (or write it for yourself in [this tutorial!](../tutorials/writing_token_contract.md))
9797
Make sure to replace this address with one of the two you created earlier.
9898

9999
#include_code deploy yarn-project/end-to-end/src/cli_docs_sandbox.test.ts bash
@@ -123,7 +123,7 @@ The `send` command expect the function name as the first unnamed argument and th
123123

124124
#include_code send yarn-project/end-to-end/src/cli_docs_sandbox.test.ts bash
125125

126-
We called the [`mint_public`](https://github.com/AztecProtocol/aztec-packages/blob/87fa621347e55f82e36c70515c1824161eee5282/yarn-project/noir-contracts/src/contracts/token_contract/src/main.nr#L157C10-L157C10) function and provided it with the 2 arguments it expects: the recipient's address and the amount to be minted. Make sure to replace all addresses in this command with yours.
126+
We called the [`mint_public`](https://github.com/AztecProtocol/aztec-packages/blob/87fa621347e55f82e36c70515c1824161eee5282/yarn-project/noir-contracts/contracts/token_contract/src/main.nr#L157C10-L157C10) function and provided it with the 2 arguments it expects: the recipient's address and the amount to be minted. Make sure to replace all addresses in this command with yours.
127127

128128
The command output tells us the details of the transaction such as its hash and status. We can use this hash to query the receipt of the transaction at a later time:
129129

docs/docs/dev_docs/cli/sandbox-reference.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ UniswapContractArtifact
174174

175175
> <sup><sub><a href="https://github.com/AztecProtocol/aztec-packages/blob/master//yarn-project/end-to-end/src/cli_docs_sandbox.test.ts#L95-L118" target="_blank" rel="noopener noreferrer">Source code: /yarn-project/end-to-end/src/cli_docs_sandbox.test.ts#L95-L118</a></sub></sup>
176176
177-
You can see all of our example contracts in the monorepo [here](https://github.com/AztecProtocol/aztec-packages/tree/master/yarn-project/noir-contracts/src/contracts).
177+
You can see all of our example contracts in the monorepo [here](https://github.com/AztecProtocol/aztec-packages/tree/master/yarn-project/noir-contracts/contracts).
178178

179179
## Boxes
180180

docs/docs/dev_docs/contracts/compiling.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ You can also generate these interfaces from prebuilt artifacts using the `genera
4242
aztec-cli generate-typescript ./path/to/my_aztec_contract_project
4343
```
4444

45-
Below is typescript code generated from the [Token](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/noir-contracts/src/contracts/token_contract/src/main.nr) contract:
45+
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:
4646

4747
```ts showLineNumbers
4848
export class TokenContract extends ContractBase {
@@ -145,7 +145,7 @@ You can also generate these interfaces from prebuilt artifacts using the `genera
145145
aztec-cli generate-noir-interface ./path/to/my_aztec_contract_project
146146
```
147147

148-
Below is an example interface, also generated from the [Token](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/noir-contracts/src/contracts/token_contract/src/main.nr) contract:
148+
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:
149149

150150
```rust
151151
impl TokenPrivateContextInterface {

docs/docs/dev_docs/contracts/example-contract.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ title: Example Aztec.nr Contract
66

77
In keeping with the origins of blockchain, here's an example of a simple private token contract. Everyone's balances are private.
88

9-
#include_code easy_private_token_contract /yarn-project/noir-contracts/src/contracts/easy_private_token_contract/src/main.nr rust
9+
#include_code easy_private_token_contract /yarn-project/noir-contracts/contracts/easy_private_token_contract/src/main.nr rust
1010

1111
:::info Disclaimer
1212
Please note that any example contract set out herein is provided solely for informational purposes only and does not constitute any inducement to use or deploy. Any implementation of any such contract with an interface or any other infrastructure should be used in accordance with applicable laws and regulations.

docs/docs/dev_docs/contracts/portals/main.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,15 @@ Note that while the `secret` and the `content` are both hashed, they are actuall
4444

4545
#include_code context_consume_l1_to_l2_message /yarn-project/aztec-nr/aztec/src/context.nr rust
4646

47-
Computing the `content` must be done manually in its current form, as we are still adding a number of bytes utilities. A good example exists within the [Token bridge example](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/util.nr).
47+
Computing the `content` must be done manually in its current form, as we are still adding a number of bytes utilities. A good example exists within the [Token bridge example](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/noir-contracts/contracts/token_bridge_contract/src/util.nr).
4848

49-
#include_code claim_public /yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/main.nr rust
49+
#include_code claim_public /yarn-project/noir-contracts/contracts/token_bridge_contract/src/main.nr rust
5050

5151
:::info
5252
The `content_hash` is a sha256 truncated to a field element (~ 254 bits). In Aztec-nr, you can use our `sha256_to_field()` to do a sha256 hash which fits in one field element
5353
:::
5454

55-
#include_code mint_public_content_hash_nr /yarn-project/noir-contracts/src/contracts/token_portal_content_hash_lib/src/lib.nr rust
55+
#include_code mint_public_content_hash_nr /yarn-project/noir-contracts/contracts/token_portal_content_hash_lib/src/lib.nr rust
5656

5757
In Solidity, you can use our `Hash.sha256ToField()` method:
5858

@@ -88,7 +88,7 @@ Access control on the L1 portal contract is essential to prevent consumption of
8888

8989
As earlier, we can use a token bridge as an example. In this case, we are burning tokens on L2 and sending a message to the portal to free them on L1.
9090

91-
#include_code exit_to_l1_private yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/main.nr rust
91+
#include_code exit_to_l1_private yarn-project/noir-contracts/contracts/token_bridge_contract/src/main.nr rust
9292

9393
When the transaction is included in a rollup block the message will be inserted into the `Outbox`, where the recipient portal can consume it from. When consuming, the `msg.sender` must match the `recipient` meaning that only portal can actually consume the message.
9494

@@ -202,4 +202,4 @@ Designated callers are enforced at the contract level for contracts that are not
202202

203203
- Token bridge (Portal contract built for L1 -> L2, i.e., a non-native L2 asset)
204204
- [Portal contract](https://github.com/AztecProtocol/aztec-packages/blob/master/l1-contracts/test/portals/TokenPortal.sol)
205-
- [Aztec contract](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/main.nr)
205+
- [Aztec contract](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/noir-contracts/contracts/token_bridge_contract/src/main.nr)

docs/docs/dev_docs/contracts/resources/common_patterns/authwit.md

+7-7
Original file line numberDiff line numberDiff line change
@@ -110,15 +110,15 @@ This function computes the message hash, and then forwards the call to the more
110110

111111
#### Example
112112

113-
#include_code assert_current_call_valid_authwit /yarn-project/noir-contracts/src/contracts/token_contract/src/main.nr rust
113+
#include_code assert_current_call_valid_authwit /yarn-project/noir-contracts/contracts/token_contract/src/main.nr rust
114114

115115
### Utilities for public calls
116116

117117
Very similar to the above, we have variations that work in the public domain. These functions are wrapped to give a similar flow for both cases, but behind the scenes the logic of the account contracts is slightly different since they cannot use the oracle as they are not in the private domain.
118118

119119
#### Example
120120

121-
#include_code assert_current_call_valid_authwit_public /yarn-project/noir-contracts/src/contracts/token_contract/src/main.nr rust
121+
#include_code assert_current_call_valid_authwit_public /yarn-project/noir-contracts/contracts/token_contract/src/main.nr rust
122122

123123
## Usage
124124

@@ -136,15 +136,15 @@ authwit = { git="https://github.com/AztecProtocol/aztec-packages/", tag="#includ
136136

137137
Then you will be able to import it into your contracts as follows.
138138

139-
#include_code import_authwit /yarn-project/noir-contracts/src/contracts/token_contract/src/main.nr rust
139+
#include_code import_authwit /yarn-project/noir-contracts/contracts/token_contract/src/main.nr rust
140140

141141
### Private Functions
142142

143143
#### Checking if the current call is authenticated
144144

145145
Based on the diagram earlier on this page let's take a look at how we can implement the `transfer` function such that it checks if the tokens are to be transferred `from` the caller or needs to be authenticated with an authentication witness.
146146

147-
#include_code transfer /yarn-project/noir-contracts/src/contracts/token_contract/src/main.nr rust
147+
#include_code transfer /yarn-project/noir-contracts/contracts/token_contract/src/main.nr rust
148148

149149
The first thing we see in the snippet above, is that if `from` is not the call we are calling the `assert_current_call_valid_authwit` function from [earlier](#private-functions). If the call is not throwing, we are all good and can continue with the transfer.
150150

@@ -162,7 +162,7 @@ With private functions covered, how can we use this in a public function? Well,
162162

163163
#### Checking if the current call is authenticated
164164

165-
#include_code transfer_public /yarn-project/noir-contracts/src/contracts/token_contract/src/main.nr rust
165+
#include_code transfer_public /yarn-project/noir-contracts/contracts/token_contract/src/main.nr rust
166166

167167
#### Authenticating an action in TypeScript
168168

@@ -178,13 +178,13 @@ We have cases where we need a non-wallet contract to approve an action to be exe
178178

179179
To support this, we must implement the `is_valid_public` function as seen in the snippet below.
180180

181-
#include_code authwit_uniswap_get /yarn-project/noir-contracts/src/contracts/uniswap_contract/src/main.nr rust
181+
#include_code authwit_uniswap_get /yarn-project/noir-contracts/contracts/uniswap_contract/src/main.nr rust
182182

183183
It also needs a way to update those storage values. Since we want the updates to be trustless, we can compute the action based on the function inputs, and then have the contract compute the key at which it must add a `true` to approve the action.
184184

185185
An example of this would be our Uniswap example which performs a cross chain swap on L1. In here, we both do private and public auth witnesses, where the public is set by the uniswap L2 contract itself. In the below snippet, you can see that we compute the action hash, and then update an `approved_action` mapping with the hash as key and `true` as value. When we then call the `token_bridge` to execute afterwards, it reads this value, burns the tokens, and consumes the authentication.
186186

187-
#include_code authwit_uniswap_set /yarn-project/noir-contracts/src/contracts/uniswap_contract/src/main.nr rust
187+
#include_code authwit_uniswap_set /yarn-project/noir-contracts/contracts/uniswap_contract/src/main.nr rust
188188

189189
Outlining more of the `swap` flow: this simplified diagram shows how it will look for contracts that are not wallets but also need to support authentication witnesses.
190190

docs/docs/dev_docs/contracts/resources/common_patterns/main.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ contract Bridge {
5757
amount: Field,
5858
) -> Field {
5959
...
60-
#include_code call_assert_token_is_same /yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/main.nr raw
60+
#include_code call_assert_token_is_same /yarn-project/noir-contracts/contracts/token_bridge_contract/src/main.nr raw
6161
}
62-
#include_code assert_token_is_same /yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/main.nr raw
62+
#include_code assert_token_is_same /yarn-project/noir-contracts/contracts/token_bridge_contract/src/main.nr raw
6363
}
6464
```
6565
:::danger
@@ -102,11 +102,11 @@ Hence, it's necessary to add a "randomness" field to your note to prevent such a
102102
Currently, if you have storage defined, the compiler will error if you don't have a `compute_note_hash_and_nullifier()` defined. Without this, the PXE can't process encrypted events and discover your notes.
103103

104104
If your contract doesn't have anything to do with notes (e.g. operates solely in the public domain), you can do the following:
105-
#include_code compute_note_hash_and_nullifier_placeholder /yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/main.nr rust
105+
#include_code compute_note_hash_and_nullifier_placeholder /yarn-project/noir-contracts/contracts/token_bridge_contract/src/main.nr rust
106106

107107
Otherwise, you need this method to help the PXE with processing your notes. In our [demo token contract](../../../tutorials/writing_token_contract.md#compute_note_hash_and_nullifier), we work with 2 kinds of notes: `ValueNote` and `TransparentNote`. Hence this method must define how to work with both:
108108

109-
#include_code compute_note_hash_and_nullifier /yarn-project/noir-contracts/src/contracts/token_contract/src/main.nr rust
109+
#include_code compute_note_hash_and_nullifier /yarn-project/noir-contracts/contracts/token_contract/src/main.nr rust
110110

111111
### L1 -- L2 interactions
112112
Refer to [Token Portal tutorial on bridging tokens between L1 and L2](../../../tutorials/token_portal/main.md) and/or [Uniswap tutorial that shows how to swap on L1 using funds on L2](../../../tutorials/uniswap/main.md). Both examples show how to:

0 commit comments

Comments
 (0)