diff --git a/docs/docs/dev_docs/getting_started/blank_box.md b/docs/docs/dev_docs/getting_started/blank_box.md new file mode 100644 index 00000000000..70a8566db18 --- /dev/null +++ b/docs/docs/dev_docs/getting_started/blank_box.md @@ -0,0 +1,129 @@ +--- +title: Aztec Boxes +--- + +This page will go over Aztec Boxes, which are full stack Aztec project templates that come with: + +- example Aztec.nr contracts +- tests written in Typescript +- web interfaces for interacting with contracts + +These can make it easier to set up a new Aztec project and get started building your app as soon as possible. + +In this page, we will break down what's included in the "blank" box. This box includes the minimum amount of code to create a full-stack Aztec dapp. + +There are also boxes that include a basic React interface (`blank-react`) and another that includes an example token contract along with a React interface (`private-token`). You can see the full list on [Github](https://github.com/AztecProtocol/aztec-packages/tree/master/yarn-project/boxes). + +## Setup + +See the Quickstart page for [requirements](./quickstart.md#requirements), starting the local [Sandbox environment](./quickstart.md#sandbox-installation) and [installing the CLI](./quickstart#cli-installation). + +Aztec Boxes use [yarn](https://classic.yarnpkg.com/) for package management, so if you want to follow along exactly, make sure you have it [installed](https://classic.yarnpkg.com/en/docs/install). + +You will also need to install Noir to compile contracts. You can find instructions for installing the latest version of Noir that is compatible with the Sandbox on the [Aztec.nr Contracts](../contracts/main.md#install-noir) page. + +## Getting the Box + +Once you have everything set up, you can get the plain "blank box" with "unbox" command: + +```bash +aztec-cli unbox blank new_project +``` + +This command indicates that you want to use the "blank" template to create a project in a directory called `new_project`. You can view the source code that is grabbed to create the project [on Github](https://github.com/AztecProtocol/aztec-packages/tree/#include_aztec_version/yarn-project/boxes). The unbox command pulls the code from the latest published version (v0.8.10 at the time of writing) for stability and compatibility. + +Running this command will give you the following structure: + +```tree +new_project +├── package.json +├── README.md +├── src +│ ├── artifacts +│ │ ├── Blank.json +│ │ └── Blank.ts +│ ├── contracts +│ │ ├── Nargo.toml +│ │ └── src +│ │ └── main.nr +│ ├── index.html +│ ├── index.ts +│ └── tests +│ └── blank.contract.test.ts +├── tsconfig.dest.json +├── tsconfig.json +├── webpack.config.js +└── yarn.lock +``` + +There may be some additional configuration files in your project, but these are the main ones. + +## Run it + +Install dependencies by running + +```bash +yarn +``` + +### Start the Sandbox + +See the Quickstart for [installing and starting the Sandbox](./quickstart.md#sandbox-installation). + +### Start the frontend + +Start the frontend with + +```bash +yarn start:dev +``` + +This will serve the web interface at `http://localhost:5173/`. + +You should see an interface with two buttons, "Deploy" and "Interact". Clicking these buttons will trigger actions in `./src/index.ts`. + +## `index.ts` + +### Imports + +`index.ts` imports functions and types from `@aztec/aztec.js`, `@aztec/foundation` and the contract ABI from `./artifacts/blank.js`. + +The contract ABI (Application Binary Interface) is generated from the contract artifact (a compiled Aztec contract) found at `./src/artifacts/Blank.json`. + +### Global variables + +The Sandbox runs on `localhost:8080` by default. With the `SANDBOX_URL`, we set up an Aztec Private Execution Client (PXE), which provides access to accounts and their private state. The PXE client helps facilitate deployments and interactions (reads and writes) with deployed contracts. + +### Imports + +`index.ts` imports from [`@aztec/aztec.js`](https://github.com/AztecProtocol/aztec-packages/tree/master/yarn-project/aztec.js). It also imports the `BlankContractAbi`, which is generated from the contract defined in `./src/contracts/src/main.nr`. + +#include_code imports yarn-project/boxes/blank/src/index.ts typescript + +### Deployment + +#include_code deploy yarn-project/boxes/blank/src/index.ts typescript + +To deploy, it gets one of the pre-initialized wallets that comes with the Sandbox with `getSandboxAccountsWallets`. Using that wallet, the contract ABI, optional salt (used to deterministically calculate the contract address, like [CREATE2 in Ethereum](https://docs.openzeppelin.com/cli/2.8/deploying-with-create2)), and the PXE, we can create a contract deployment transaction and send it to the sandbox network. The constructor defined in the Blank contract doesn't take any arguments, so we pass an empty array. + +With the web interface running, open your browser dev tools console, click the "Deploy" button and see the successfully deployed contract address. In the terminal or Docker logs where your sandbox is running, you will see transaction and block production info printed. + +### Interaction + +#include_code interact yarn-project/boxes/blank/src/index.ts typescript + +Once a contract is deployed, you can interact with it by clicking the "Interact" button. This will call the `getPublicKey` function on the `Blank` contract. For this call we need to pass the contract, the contract abi, the name of the function to call, the arguments for the function, the PXE and the wallet from which to make the transaction, see `callContractFunction`. + +### Compiling Contracts + +This blank project comes with the contract artifacts, which are generated when the contracts are compiled, out of the box. + +You can modify the source contracts and regenerate the artifacts by running + +```bash +yarn compile +``` + +This will generate a [contract artifact](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/boxes/blank/src/artifacts/Blank.json) and TypeScript class for the [Aztec smart contract](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/boxes/blank/src/contracts/src/main.nr), which the frontend uses to generate the UI. + +After compiling, you can re-deploy the updated noir smart contract from the web UI. The function interaction forms are generated from parsing the contract artifact, so they should update automatically after you recompile. diff --git a/docs/sidebars.js b/docs/sidebars.js index 16ee56aa1fa..2e35c1d1e7d 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -199,6 +199,7 @@ const sidebars = { items: [ "dev_docs/getting_started/quickstart", "dev_docs/getting_started/sandbox", + "dev_docs/getting_started/blank_box", "dev_docs/getting_started/updating", ], }, diff --git a/yarn-project/boxes/blank/src/index.ts b/yarn-project/boxes/blank/src/index.ts index 98bdda3c830..45e6bebde76 100644 --- a/yarn-project/boxes/blank/src/index.ts +++ b/yarn-project/boxes/blank/src/index.ts @@ -1,3 +1,4 @@ +// docs:start:imports import { BlankContractArtifact } from './artifacts/Blank.js'; import { AccountWallet, @@ -13,6 +14,7 @@ import { } from '@aztec/aztec.js'; import { ContractArtifact, FunctionArtifact, encodeArguments } from '@aztec/foundation/abi'; import { FieldsOf } from '@aztec/foundation/types'; +// docs:end:imports export const contractArtifact: ContractArtifact = BlankContractArtifact; @@ -35,7 +37,7 @@ if (typeof document !== 'undefined') { console.log('Interaction transaction succeeded', interactionResult); }); } - +// docs:start:deploy export async function handleDeployClick(): Promise { // eslint-disable-next-line no-console console.log('Deploying Contract'); @@ -51,7 +53,8 @@ export async function handleDeployClick(): Promise { return contractAztecAddress.toString(); } - +// docs:end:deploy +// docs:start:interact export async function handleInteractClick(contractAddress: string) { const [wallet, ..._rest] = await getSandboxAccountsWallets(pxe); const callArgs = { address: wallet.getCompleteAddress().address }; @@ -70,7 +73,7 @@ export async function handleInteractClick(contractAddress: string) { wallet.getCompleteAddress(), ); } - +// docs:end:interact export const getFunctionAbi = (contractAbi: any, functionName: string) => { const functionAbi = contractAbi.functions.find((f: FunctionArtifact) => f.name === functionName); if (!functionAbi) throw new Error(`Function ${functionName} not found in abi`);