diff --git a/docs/docs/dev_docs/tutorials/token_portal/typescript_glue_code.md b/docs/docs/dev_docs/tutorials/token_portal/typescript_glue_code.md index ae99c000411..8ed8d53a4a9 100644 --- a/docs/docs/dev_docs/tutorials/token_portal/typescript_glue_code.md +++ b/docs/docs/dev_docs/tutorials/token_portal/typescript_glue_code.md @@ -62,7 +62,7 @@ const [TokenPortalAbi, TokenPortalBytecode] = #include_code deployL1Contract /yarn-project/ethereum/src/deploy_l1_contracts.ts typescript raw -#include_code deployAndInitializeTokenAndBridgeContracts /yarn-project/end-to-end/src/fixtures/utils.ts typescript raw +#include_code deployAndInitializeTokenAndBridgeContracts /yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts typescript raw #include_code delay /yarn-project/end-to-end/src/fixtures/utils.ts typescript raw ``` @@ -77,7 +77,7 @@ Now let's create another util file to can handle interaction with these contract In `cross_chain_test_harness.ts`, add: -#include_code cross_chain_test_harness /yarn-project/end-to-end/src/fixtures/cross_chain_test_harness.ts typescript +#include_code cross_chain_test_harness /yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts typescript This is a class that holds all contracts as objects and exposes easy to use helper methods to interact with our contracts. @@ -90,7 +90,7 @@ import { expect, jest} from '@jest/globals' import { AccountWallet, AztecAddress, DebugLogger, EthAddress, Fr, computeAuthWitMessageHash, createDebugLogger, createPXEClient, getSandboxAccountsWallets, waitForSandbox } from '@aztec/aztec.js'; import { TokenBridgeContract, TokenContract } from '@aztec/noir-contracts/types'; -import { CrossChainTestHarness } from './fixtures/cross_chain_test_harness.js'; +import { CrossChainTestHarness } from './shared/cross_chain_test_harness.js'; import { delay } from './fixtures/utils.js'; import { mnemonicToAccount } from 'viem/accounts'; import { createPublicClient, createWalletClient, http } from 'viem'; diff --git a/docs/docs/dev_docs/tutorials/uniswap/typescript_glue_code.md b/docs/docs/dev_docs/tutorials/uniswap/typescript_glue_code.md index 887786a5a9d..f4e793e2a4d 100644 --- a/docs/docs/dev_docs/tutorials/uniswap/typescript_glue_code.md +++ b/docs/docs/dev_docs/tutorials/uniswap/typescript_glue_code.md @@ -58,6 +58,7 @@ export FORK_URL= ``` Now rerun the sandbox: + ```sh /bin/sh -c "$(curl -fsSL 'https://sandbox.aztec.network')" ``` @@ -94,7 +95,7 @@ import { parseEther, } from "viem"; import { foundry } from "viem/chains"; -import { CrossChainTestHarness } from "./fixtures/cross_chain_test_harness.js"; +import { CrossChainTestHarness } from "./shared/cross_chain_test_harness.js"; import { UniswapContract } from "./fixtures/Uniswap.js"; import { beforeAll, expect, jest } from "@jest/globals"; import { @@ -113,18 +114,18 @@ const MNEMONIC = "test test test test test test test test test test test junk"; const hdAccount = mnemonicToAccount(MNEMONIC); const expectedForkBlockNumber = 17514288; -#include_code uniswap_l1_l2_test_setup_const yarn-project/end-to-end/src/canary/uniswap_l1_l2.ts typescript raw +#include_code uniswap_l1_l2_test_setup_const yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts typescript raw #include_code uniswap_setup yarn-project/canary/src/uniswap_trade_on_l1_from_l2.test.ts typescript raw -#include_code uniswap_l1_l2_test_beforeAll yarn-project/end-to-end/src/canary/uniswap_l1_l2.ts typescript raw +#include_code uniswap_l1_l2_test_beforeAll yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts typescript raw ``` ## Private flow test -#include_code uniswap_private yarn-project/end-to-end/src/canary/uniswap_l1_l2.ts typescript +#include_code uniswap_private yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts typescript ## Public flow test -#include_code uniswap_public yarn-project/end-to-end/src/canary/uniswap_l1_l2.ts typescript +#include_code uniswap_public yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts typescript ## Running the test diff --git a/yarn-project/Dockerfile b/yarn-project/Dockerfile index 331795d6dc0..ee4f1455cb8 100644 --- a/yarn-project/Dockerfile +++ b/yarn-project/Dockerfile @@ -17,6 +17,9 @@ RUN rm -rf noir-contracts/target # Build the entire project. RUN yarn tsc -b +# Build aztec.js web artifact +RUN cd /usr/src/yarn-project/aztec.js && yarn build:web + FROM 278380418400.dkr.ecr.eu-west-2.amazonaws.com/yarn-project-base COPY --from=builder /usr/src/yarn-project /usr/src/yarn-project diff --git a/yarn-project/aztec.js/src/index.ts b/yarn-project/aztec.js/src/index.ts index 49d7c3b30dc..b84e1383946 100644 --- a/yarn-project/aztec.js/src/index.ts +++ b/yarn-project/aztec.js/src/index.ts @@ -11,28 +11,37 @@ export * from './wallet/index.js'; // here once the issue is resolved. export { AztecAddress, EthAddress, Point, Fr, FunctionSelector, GrumpkinScalar } from '@aztec/circuits.js'; export { - PXE, ContractData, - ExtendedContractData as ExtendedContractData, DeployedContract, + ExtendedContractData as ExtendedContractData, FunctionCall, + GrumpkinPrivateKey, L2BlockL2Logs, LogFilter, - UnencryptedL2Log, NodeInfo, NotePreimage, PackedArguments, PublicKey, - GrumpkinPrivateKey, + PXE, SyncStatus, Tx, TxExecutionRequest, TxHash, TxReceipt, TxStatus, + UnencryptedL2Log, emptyFunctionCall, } from '@aztec/types'; export { ContractArtifact } from '@aztec/foundation/abi'; export { createDebugLogger, DebugLogger } from '@aztec/foundation/log'; export { fileURLToPath } from '@aztec/foundation/url'; export { sleep } from '@aztec/foundation/sleep'; +export { retry, retryUntil } from '@aztec/foundation/retry'; +export * from '@aztec/foundation/crypto'; + +export { + deployL1Contract, + deployL1Contracts, + DeployL1Contracts, + L1ContractArtifactsForDeployment, +} from '@aztec/ethereum'; diff --git a/yarn-project/canary/Dockerfile b/yarn-project/canary/Dockerfile index 6b237840b44..e3aaabc9d18 100644 --- a/yarn-project/canary/Dockerfile +++ b/yarn-project/canary/Dockerfile @@ -1,37 +1,38 @@ -FROM 278380418400.dkr.ecr.eu-west-2.amazonaws.com/yarn-project AS builder -ARG COMMIT_TAG="." +FROM node:18-alpine AS builder + +RUN apk update && apk add --no-cache bash jq curl + +COPY ./end-to-end /usr/src/end-to-end +COPY ./canary /usr/src/canary # Setup & Build end-to-end package -WORKDIR /usr/src/yarn-project/end-to-end +WORKDIR /usr/src/end-to-end # Extract canary @aztec dependencies RUN ../canary/scripts/extract_packages.sh ../canary/package.json > ./target_pkgs.txt # Update end-to-end dependencies with target version -RUN ./scripts/setup_canary.sh "$COMMIT_TAG" ./target_pkgs.txt +RUN ./scripts/setup_canary.sh ./target_pkgs.txt package.json RUN rm ./target_pkgs.txt +# yarn install & build to apply changes (canary packages) +RUN yarn && yarn build -# Build canary package -WORKDIR /usr/src/yarn-project/canary -RUN ./scripts/update_packages.sh "$COMMIT_TAG" +# Install & build canary packages +WORKDIR /usr/src/canary +RUN ./scripts/update_packages.sh canary ../end-to-end/ +RUN yarn && yarn build FROM node:18-alpine -RUN apk update && apk add --no-cache udev ttf-freefont chromium curl jq bash -ENV CHROME_BIN="/usr/bin/chromium-browser" PUPPETEER_SKIP_CHROMIUM_DOWNLOAD="true" - -COPY --from=builder /usr/src/ /usr/src/ -WORKDIR /usr/src/yarn-project/canary - -RUN apk update && apk add --no-cache udev ttf-freefont chromium curl jq bash +RUN apk update && apk add --no-cache udev ttf-freefont chromium bash ENV CHROME_BIN="/usr/bin/chromium-browser" PUPPETEER_SKIP_CHROMIUM_DOWNLOAD="true" -# Copy web artifacts for browser test -WORKDIR /usr/src/yarn-project/aztec.js -RUN yarn build:web -WORKDIR /usr/src/yarn-project/canary +COPY --from=builder /usr/src/end-to-end /usr/src/end-to-end +COPY --from=builder /usr/src/canary /usr/src/canary +WORKDIR /usr/src/canary # Copy browser script RUN cp ../end-to-end/scripts/start_e2e_ci_browser.sh ./scripts/start_e2e_ci_browser.sh RUN chmod +x scripts/start_e2e_ci_browser.sh -RUN cp ../aztec.js/dest/main.js src/web/ -RUN cp ../circuits.js/resources/aztec3-circuits.wasm src/web/ +RUN cp ./node_modules/@aztec/circuits.js/resources/aztec3-circuits.wasm src/web/ +RUN cp ./node_modules/@aztec/aztec.js/dest/main.js src/web/ + ENTRYPOINT ["yarn", "test"] diff --git a/yarn-project/canary/package.json b/yarn-project/canary/package.json index 4bdaf4e0495..8952f796622 100644 --- a/yarn-project/canary/package.json +++ b/yarn-project/canary/package.json @@ -22,7 +22,11 @@ }, "dependencies": { "@aztec/aztec.js": "workspace:^", + "@aztec/cli": "workspace:^", "@aztec/end-to-end": "workspace:^", + "@aztec/ethereum": "workspace:^", + "@aztec/l1-artifacts": "workspace:^", + "@aztec/noir-contracts": "workspace:^", "@jest/globals": "^29.5.0", "@types/jest": "^29.5.0", "@types/koa-static": "^4.0.2", diff --git a/yarn-project/canary/scripts/update_packages.sh b/yarn-project/canary/scripts/update_packages.sh index ce020291a73..c8fe7740bb7 100755 --- a/yarn-project/canary/scripts/update_packages.sh +++ b/yarn-project/canary/scripts/update_packages.sh @@ -2,6 +2,7 @@ set -eu DIST_TAG=$1 +E2E_DIR=$2 if [ -z "$DIST_TAG" ]; then echo "No dist tag provided." @@ -11,8 +12,13 @@ fi echo "Updating Aztec dependencies to tag $DIST_TAG" TMP=$(mktemp) +# Update NPM dependencies to dist tag for PKG in $(jq --raw-output ".dependencies | keys[] | select(contains(\"@aztec/\") and (. != \"@aztec/end-to-end\"))" package.json); do jq --arg v $DIST_TAG ".dependencies[\"$PKG\"] = \$v" package.json >$TMP && mv $TMP package.json done +# Update end-to-end to local dependency +TMP=$(mktemp) +jq --arg dir "file:$E2E_DIR" '.dependencies["@aztec/end-to-end"] = $dir' package.json >$TMP && mv $TMP package.json + jq ".references = []" tsconfig.json >$TMP && mv $TMP tsconfig.json diff --git a/yarn-project/canary/tsconfig.json b/yarn-project/canary/tsconfig.json index 2e42dbb2f9a..a80b4f11c64 100644 --- a/yarn-project/canary/tsconfig.json +++ b/yarn-project/canary/tsconfig.json @@ -22,8 +22,20 @@ { "path": "../aztec.js" }, + { + "path": "../cli" + }, { "path": "../end-to-end" + }, + { + "path": "../ethereum" + }, + { + "path": "../l1-artifacts" + }, + { + "path": "../noir-contracts" } ], "include": ["src"] diff --git a/yarn-project/end-to-end/scripts/setup_canary.sh b/yarn-project/end-to-end/scripts/setup_canary.sh index db900ca2843..2d4cd7fa2ef 100755 --- a/yarn-project/end-to-end/scripts/setup_canary.sh +++ b/yarn-project/end-to-end/scripts/setup_canary.sh @@ -1,8 +1,9 @@ #!/bin/bash set -eu -DIST_TAG=$1 -TARGET_PKGS_FILE=$2 +TARGET_PKGS_FILE=$1 + +DIST_TAG=canary # Check if file exists and read it into an array if [ -f "$TARGET_PKGS_FILE" ]; then @@ -26,14 +27,14 @@ cd "$TARGET_DIR" # Loop through all files and folders in the directory for item in $(ls -A); do - if [[ "$item" != "index.ts" && "$item" != "canary" ]]; then + if [[ "$item" != "index.ts" && "$item" != "shared" ]]; then # Remove the item (either file or folder) rm -rf "$item" fi done cd .. -echo "Updating external Aztec dependencies to tag $DIST_TAG" +echo "Updating external Aztec dependencies to tag '$DIST_TAG'" JSON_TARGET_PKGS=$(printf '%s\n' "${TARGET_PKGS[@]}" | jq -R -s -c 'split("\n") | map(select(. != ""))') TMP=$(mktemp) @@ -54,4 +55,8 @@ jq --arg v $DIST_TAG --argjson target_pkgs "$JSON_TARGET_PKGS" ' end )' package.json >$TMP && mv $TMP package.json -jq ".references = []" tsconfig.json >$TMP && mv $TMP tsconfig.json +echo "Updating end-to-end tsconfig.json" +TMP=$(mktemp) +# Copy canary's tsconfig.json +cp ../canary/tsconfig.json tsconfig.json +jq 'del(.references)' tsconfig.json >$TMP && mv $TMP tsconfig.json diff --git a/yarn-project/end-to-end/src/e2e_aztec_js_browser.test.ts b/yarn-project/end-to-end/src/e2e_aztec_js_browser.test.ts index aa88cdbbe18..b34bdb5334b 100644 --- a/yarn-project/end-to-end/src/e2e_aztec_js_browser.test.ts +++ b/yarn-project/end-to-end/src/e2e_aztec_js_browser.test.ts @@ -4,7 +4,7 @@ import Koa from 'koa'; import serve from 'koa-static'; import path, { dirname } from 'path'; -import { browserTestSuite } from './canary/browser.js'; +import { browserTestSuite } from './shared/browser.js'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); diff --git a/yarn-project/end-to-end/src/e2e_cli.test.ts b/yarn-project/end-to-end/src/e2e_cli.test.ts index 1f24698ce1e..dd527374372 100644 --- a/yarn-project/end-to-end/src/e2e_cli.test.ts +++ b/yarn-project/end-to-end/src/e2e_cli.test.ts @@ -2,8 +2,8 @@ import { startHttpRpcServer } from '@aztec/aztec-sandbox'; import { PXE, createDebugLogger } from '@aztec/aztec.js'; import { createPXERpcServer } from '@aztec/pxe'; -import { cliTestSuite } from './canary/cli.js'; import { setup as e2eSetup } from './fixtures/utils.js'; +import { cliTestSuite } from './shared/cli.js'; const HTTP_PORT = 9009; const RPC_URL = `http://localhost:${HTTP_PORT}`; diff --git a/yarn-project/end-to-end/src/e2e_cross_chain_messaging.test.ts b/yarn-project/end-to-end/src/e2e_cross_chain_messaging.test.ts index 3f4fbd352f6..b0eca576525 100644 --- a/yarn-project/end-to-end/src/e2e_cross_chain_messaging.test.ts +++ b/yarn-project/end-to-end/src/e2e_cross_chain_messaging.test.ts @@ -9,8 +9,8 @@ import { } from '@aztec/aztec.js'; import { TokenBridgeContract, TokenContract } from '@aztec/noir-contracts/types'; -import { CrossChainTestHarness } from './fixtures/cross_chain_test_harness.js'; import { delay, setup } from './fixtures/utils.js'; +import { CrossChainTestHarness } from './shared/cross_chain_test_harness.js'; describe('e2e_cross_chain_messaging', () => { let logger: DebugLogger; diff --git a/yarn-project/end-to-end/src/e2e_public_cross_chain_messaging.test.ts b/yarn-project/end-to-end/src/e2e_public_cross_chain_messaging.test.ts index 082a6aad120..d42b21af784 100644 --- a/yarn-project/end-to-end/src/e2e_public_cross_chain_messaging.test.ts +++ b/yarn-project/end-to-end/src/e2e_public_cross_chain_messaging.test.ts @@ -5,8 +5,8 @@ import { DebugLogger } from '@aztec/foundation/log'; import { TokenBridgeContract, TokenContract } from '@aztec/noir-contracts/types'; import { TxStatus } from '@aztec/types'; -import { CrossChainTestHarness } from './fixtures/cross_chain_test_harness.js'; import { delay, setup } from './fixtures/utils.js'; +import { CrossChainTestHarness } from './shared/cross_chain_test_harness.js'; describe('e2e_public_cross_chain_messaging', () => { let logger: DebugLogger; diff --git a/yarn-project/end-to-end/src/e2e_public_to_private_messaging.test.ts b/yarn-project/end-to-end/src/e2e_public_to_private_messaging.test.ts index df236df5ec8..87bfafa399f 100644 --- a/yarn-project/end-to-end/src/e2e_public_to_private_messaging.test.ts +++ b/yarn-project/end-to-end/src/e2e_public_to_private_messaging.test.ts @@ -2,8 +2,8 @@ import { AztecAddress } from '@aztec/aztec.js'; import { EthAddress } from '@aztec/circuits.js'; import { DebugLogger } from '@aztec/foundation/log'; -import { CrossChainTestHarness } from './fixtures/cross_chain_test_harness.js'; import { delay, setup } from './fixtures/utils.js'; +import { CrossChainTestHarness } from './shared/cross_chain_test_harness.js'; describe('e2e_public_to_private_messaging', () => { let logger: DebugLogger; diff --git a/yarn-project/end-to-end/src/fixtures/utils.ts b/yarn-project/end-to-end/src/fixtures/utils.ts index 601aeddc2a9..8c922c1114f 100644 --- a/yarn-project/end-to-end/src/fixtures/utils.ts +++ b/yarn-project/end-to-end/src/fixtures/utils.ts @@ -1,24 +1,17 @@ import { AztecNodeConfig, AztecNodeService, getConfigEnvVars } from '@aztec/aztec-node'; import { AccountWalletWithPrivateKey, - AztecAddress, CheatCodes, CompleteAddress, - EthAddress, + DebugLogger, EthCheatCodes, SentTx, - Wallet, createAccounts, + createDebugLogger, createPXEClient, getSandboxAccountsWallets, } from '@aztec/aztec.js'; -import { - DeployL1Contracts, - L1ContractArtifactsForDeployment, - deployL1Contract, - deployL1Contracts, -} from '@aztec/ethereum'; -import { DebugLogger, createDebugLogger } from '@aztec/foundation/log'; +import { DeployL1Contracts, L1ContractArtifactsForDeployment, deployL1Contracts } from '@aztec/ethereum'; import { retryUntil } from '@aztec/foundation/retry'; import { ContractDeploymentEmitterAbi, @@ -29,18 +22,13 @@ import { InboxBytecode, OutboxAbi, OutboxBytecode, - PortalERC20Abi, - PortalERC20Bytecode, RegistryAbi, RegistryBytecode, RollupAbi, RollupBytecode, - TokenPortalAbi, - TokenPortalBytecode, } from '@aztec/l1-artifacts'; -import { TokenBridgeContract, TokenContract } from '@aztec/noir-contracts/types'; import { PXEService, createPXEService, getPXEServiceConfig } from '@aztec/pxe'; -import { AztecNode, L2BlockL2Logs, LogType, PXE, TxStatus, createAztecNodeRpcClient } from '@aztec/types'; +import { AztecNode, L2BlockL2Logs, LogType, PXE, createAztecNodeRpcClient } from '@aztec/types'; import * as path from 'path'; import { @@ -49,11 +37,8 @@ import { HDAccount, HttpTransport, PrivateKeyAccount, - PublicClient, - WalletClient, createPublicClient, createWalletClient, - getContract, http, } from 'viem'; import { mnemonicToAccount } from 'viem/accounts'; @@ -61,6 +46,8 @@ import { mnemonicToAccount } from 'viem/accounts'; import { MNEMONIC, localAnvil } from './fixtures.js'; import { isMetricsLoggingRequested, setupMetricsLogger } from './logging.js'; +export { deployAndInitializeTokenAndBridgeContracts } from '../shared/cross_chain_test_harness.js'; + const { PXE_URL = '', AZTEC_NODE_URL = '' } = process.env; const getAztecNodeUrl = () => { @@ -338,100 +325,6 @@ export function getLogger() { return createDebugLogger('aztec:' + describeBlockName); } -// docs:start:deployAndInitializeTokenAndBridgeContracts -/** - * Deploy L1 token and portal, initialize portal, deploy a non native l2 token contract, its L2 bridge contract and attach is to the portal. - * @param wallet - the wallet instance - * @param walletClient - A viem WalletClient. - * @param publicClient - A viem PublicClient. - * @param rollupRegistryAddress - address of rollup registry to pass to initialize the token portal - * @param owner - owner of the L2 contract - * @param underlyingERC20Address - address of the underlying ERC20 contract to use (if none supplied, it deploys one) - * @returns l2 contract instance, bridge contract instance, token portal instance, token portal address and the underlying ERC20 instance - */ -export async function deployAndInitializeTokenAndBridgeContracts( - wallet: Wallet, - walletClient: WalletClient, - publicClient: PublicClient, - rollupRegistryAddress: EthAddress, - owner: AztecAddress, - underlyingERC20Address?: EthAddress, -): Promise<{ - /** - * The L2 token contract instance. - */ - token: TokenContract; - /** - * The L2 bridge contract instance. - */ - bridge: TokenBridgeContract; - /** - * The token portal contract address. - */ - tokenPortalAddress: EthAddress; - /** - * The token portal contract instance - */ - tokenPortal: any; - /** - * The underlying ERC20 contract instance. - */ - underlyingERC20: any; -}> { - if (!underlyingERC20Address) { - underlyingERC20Address = await deployL1Contract(walletClient, publicClient, PortalERC20Abi, PortalERC20Bytecode); - } - const underlyingERC20 = getContract({ - address: underlyingERC20Address.toString(), - abi: PortalERC20Abi, - walletClient, - publicClient, - }); - - // deploy the token portal - const tokenPortalAddress = await deployL1Contract(walletClient, publicClient, TokenPortalAbi, TokenPortalBytecode); - const tokenPortal = getContract({ - address: tokenPortalAddress.toString(), - abi: TokenPortalAbi, - walletClient, - publicClient, - }); - - // deploy l2 token - const deployTx = TokenContract.deploy(wallet, owner).send(); - - // now wait for the deploy txs to be mined. This way we send all tx in the same rollup. - const deployReceipt = await deployTx.wait(); - if (deployReceipt.status !== TxStatus.MINED) throw new Error(`Deploy token tx status is ${deployReceipt.status}`); - const token = await TokenContract.at(deployReceipt.contractAddress!, wallet); - - // deploy l2 token bridge and attach to the portal - const bridge = await TokenBridgeContract.deploy(wallet, token.address) - .send({ portalContract: tokenPortalAddress }) - .deployed(); - - if ((await token.methods.admin().view()) !== owner.toBigInt()) throw new Error(`Token admin is not ${owner}`); - - if ((await bridge.methods.token().view()) !== token.address.toBigInt()) - throw new Error(`Bridge token is not ${token.address}`); - - // make the bridge a minter on the token: - const makeMinterTx = token.methods.set_minter(bridge.address, true).send(); - const makeMinterReceipt = await makeMinterTx.wait(); - if (makeMinterReceipt.status !== TxStatus.MINED) - throw new Error(`Make bridge a minter tx status is ${makeMinterReceipt.status}`); - if ((await token.methods.is_minter(bridge.address).view()) === 1n) throw new Error(`Bridge is not a minter`); - - // initialize portal - await tokenPortal.write.initialize( - [rollupRegistryAddress.toString(), underlyingERC20Address.toString(), bridge.address.toString()], - {} as any, - ); - - return { token, bridge, tokenPortalAddress, tokenPortal, underlyingERC20 }; -} -// docs:end:deployAndInitializeTokenAndBridgeContracts - // docs:start:delay /** * Sleep for a given number of milliseconds. diff --git a/yarn-project/end-to-end/src/index.ts b/yarn-project/end-to-end/src/index.ts index da0a55181ff..a6286441418 100644 --- a/yarn-project/end-to-end/src/index.ts +++ b/yarn-project/end-to-end/src/index.ts @@ -1,5 +1,5 @@ // Should only export tests from the canary directory -export { cliTestSuite } from './canary/cli.js'; -export { browserTestSuite } from './canary/browser.js'; -export { uniswapL1L2TestSuite, UniswapSetupContext } from './canary/uniswap_l1_l2.js'; +export { cliTestSuite } from './shared/cli.js'; +export { browserTestSuite } from './shared/browser.js'; +export { uniswapL1L2TestSuite, UniswapSetupContext } from './shared/uniswap_l1_l2.js'; diff --git a/yarn-project/end-to-end/src/canary/browser.ts b/yarn-project/end-to-end/src/shared/browser.ts similarity index 100% rename from yarn-project/end-to-end/src/canary/browser.ts rename to yarn-project/end-to-end/src/shared/browser.ts diff --git a/yarn-project/end-to-end/src/canary/cli.ts b/yarn-project/end-to-end/src/shared/cli.ts similarity index 100% rename from yarn-project/end-to-end/src/canary/cli.ts rename to yarn-project/end-to-end/src/shared/cli.ts diff --git a/yarn-project/end-to-end/src/fixtures/cross_chain_test_harness.ts b/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts similarity index 73% rename from yarn-project/end-to-end/src/fixtures/cross_chain_test_harness.ts rename to yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts index 2a173c1e597..e76d58caab9 100644 --- a/yarn-project/end-to-end/src/fixtures/cross_chain_test_harness.ts +++ b/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts @@ -1,13 +1,122 @@ // docs:start:cross_chain_test_harness -import { AztecAddress, DebugLogger, EthAddress, Fr, TxHash, Wallet, computeMessageSecretHash } from '@aztec/aztec.js'; -import { sha256ToField } from '@aztec/foundation/crypto'; -import { OutboxAbi } from '@aztec/l1-artifacts'; +import { + AztecAddress, + DebugLogger, + EthAddress, + Fr, + NotePreimage, + PXE, + TxHash, + TxStatus, + Wallet, + computeMessageSecretHash, + deployL1Contract, + sha256ToField, +} from '@aztec/aztec.js'; +import { + OutboxAbi, + PortalERC20Abi, + PortalERC20Bytecode, + TokenPortalAbi, + TokenPortalBytecode, +} from '@aztec/l1-artifacts'; import { TokenBridgeContract, TokenContract } from '@aztec/noir-contracts/types'; -import { NotePreimage, PXE, TxStatus } from '@aztec/types'; -import { Chain, HttpTransport, PublicClient, getContract, getFunctionSelector } from 'viem'; +import { Account, Chain, HttpTransport, PublicClient, WalletClient, getContract, getFunctionSelector } from 'viem'; -import { deployAndInitializeTokenAndBridgeContracts } from './utils.js'; +// docs:start:deployAndInitializeTokenAndBridgeContracts +/** + * Deploy L1 token and portal, initialize portal, deploy a non native l2 token contract, its L2 bridge contract and attach is to the portal. + * @param wallet - the wallet instance + * @param walletClient - A viem WalletClient. + * @param publicClient - A viem PublicClient. + * @param rollupRegistryAddress - address of rollup registry to pass to initialize the token portal + * @param owner - owner of the L2 contract + * @param underlyingERC20Address - address of the underlying ERC20 contract to use (if none supplied, it deploys one) + * @returns l2 contract instance, bridge contract instance, token portal instance, token portal address and the underlying ERC20 instance + */ +export async function deployAndInitializeTokenAndBridgeContracts( + wallet: Wallet, + walletClient: WalletClient, + publicClient: PublicClient, + rollupRegistryAddress: EthAddress, + owner: AztecAddress, + underlyingERC20Address?: EthAddress, +): Promise<{ + /** + * The L2 token contract instance. + */ + token: TokenContract; + /** + * The L2 bridge contract instance. + */ + bridge: TokenBridgeContract; + /** + * The token portal contract address. + */ + tokenPortalAddress: EthAddress; + /** + * The token portal contract instance + */ + tokenPortal: any; + /** + * The underlying ERC20 contract instance. + */ + underlyingERC20: any; +}> { + if (!underlyingERC20Address) { + underlyingERC20Address = await deployL1Contract(walletClient, publicClient, PortalERC20Abi, PortalERC20Bytecode); + } + const underlyingERC20 = getContract({ + address: underlyingERC20Address.toString(), + abi: PortalERC20Abi, + walletClient, + publicClient, + }); + + // deploy the token portal + const tokenPortalAddress = await deployL1Contract(walletClient, publicClient, TokenPortalAbi, TokenPortalBytecode); + const tokenPortal = getContract({ + address: tokenPortalAddress.toString(), + abi: TokenPortalAbi, + walletClient, + publicClient, + }); + + // deploy l2 token + const deployTx = TokenContract.deploy(wallet, owner).send(); + + // now wait for the deploy txs to be mined. This way we send all tx in the same rollup. + const deployReceipt = await deployTx.wait(); + if (deployReceipt.status !== TxStatus.MINED) throw new Error(`Deploy token tx status is ${deployReceipt.status}`); + const token = await TokenContract.at(deployReceipt.contractAddress!, wallet); + + // deploy l2 token bridge and attach to the portal + const bridge = await TokenBridgeContract.deploy(wallet, token.address) + .send({ portalContract: tokenPortalAddress }) + .deployed(); + + if ((await token.methods.admin().view()) !== owner.toBigInt()) throw new Error(`Token admin is not ${owner}`); + + if ((await bridge.methods.token().view()) !== token.address.toBigInt()) + throw new Error(`Bridge token is not ${token.address}`); + + // make the bridge a minter on the token: + const makeMinterTx = token.methods.set_minter(bridge.address, true).send(); + const makeMinterReceipt = await makeMinterTx.wait(); + if (makeMinterReceipt.status !== TxStatus.MINED) + throw new Error(`Make bridge a minter tx status is ${makeMinterReceipt.status}`); + if ((await token.methods.is_minter(bridge.address).view()) === 1n) throw new Error(`Bridge is not a minter`); + + // initialize portal + await tokenPortal.write.initialize( + [rollupRegistryAddress.toString(), underlyingERC20Address.toString(), bridge.address.toString()], + {} as any, + ); + + return { token, bridge, tokenPortalAddress, tokenPortal, underlyingERC20 }; +} +// docs:end:deployAndInitializeTokenAndBridgeContracts /** * A Class for testing cross chain interactions, contains common interactions diff --git a/yarn-project/end-to-end/src/canary/uniswap_l1_l2.ts b/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts similarity index 99% rename from yarn-project/end-to-end/src/canary/uniswap_l1_l2.ts rename to yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts index ab45ab2fac0..b7385ee3440 100644 --- a/yarn-project/end-to-end/src/canary/uniswap_l1_l2.ts +++ b/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts @@ -7,6 +7,7 @@ import { PXE, TxStatus, computeAuthWitMessageHash, + sleep, } from '@aztec/aztec.js'; import { deployL1Contract } from '@aztec/ethereum'; import { UniswapPortalAbi, UniswapPortalBytecode } from '@aztec/l1-artifacts'; @@ -15,8 +16,7 @@ import { UniswapContract } from '@aztec/noir-contracts/types'; import { jest } from '@jest/globals'; import { Chain, HttpTransport, PublicClient, getContract, parseEther } from 'viem'; -import { CrossChainTestHarness } from '../fixtures/cross_chain_test_harness.js'; -import { delay } from '../fixtures/utils.js'; +import { CrossChainTestHarness } from './cross_chain_test_harness.js'; // PSA: This tests works on forked mainnet. There is a dump of the data in `dumpedState` such that we // don't need to burn through RPC requests. @@ -173,7 +173,7 @@ export const uniswapL1L2TestSuite = ( ); // Wait for the archiver to process the message - await delay(5000); + await sleep(5000); // Perform an unrelated transaction on L2 to progress the rollup. Here we mint public tokens. await wethCrossChainHarness.mintTokensPublicOnL2(0n); @@ -273,7 +273,7 @@ export const uniswapL1L2TestSuite = ( const daiAmountToBridge = BigInt(daiL1BalanceOfPortalAfter - daiL1BalanceOfPortalBeforeSwap); // Wait for the archiver to process the message - await delay(5000); + await sleep(5000); // send a transfer tx to force through rollup with the message included await wethCrossChainHarness.mintTokensPublicOnL2(0n); @@ -319,7 +319,7 @@ export const uniswapL1L2TestSuite = ( ); // Wait for the archiver to process the message - await delay(5000); + await sleep(5000); // Perform an unrelated transaction on L2 to progress the rollup. Here we transfer 0 tokens await wethCrossChainHarness.mintTokensPublicOnL2(0n); @@ -420,7 +420,7 @@ export const uniswapL1L2TestSuite = ( const daiAmountToBridge = BigInt(daiL1BalanceOfPortalAfter - daiL1BalanceOfPortalBeforeSwap); // Wait for the archiver to process the message - await delay(5000); + await sleep(5000); // send a transfer tx to force through rollup with the message included await wethCrossChainHarness.mintTokensPublicOnL2(0n); diff --git a/yarn-project/end-to-end/src/uniswap_trade_on_l1_from_l2.test.ts b/yarn-project/end-to-end/src/uniswap_trade_on_l1_from_l2.test.ts index b96cf35b4cd..9bc5db2f362 100644 --- a/yarn-project/end-to-end/src/uniswap_trade_on_l1_from_l2.test.ts +++ b/yarn-project/end-to-end/src/uniswap_trade_on_l1_from_l2.test.ts @@ -1,5 +1,5 @@ -import { UniswapSetupContext, uniswapL1L2TestSuite } from './canary/uniswap_l1_l2.js'; import { setup as e2eSetup } from './fixtures/utils.js'; +import { UniswapSetupContext, uniswapL1L2TestSuite } from './shared/uniswap_l1_l2.js'; // This tests works on forked mainnet. There is a dump of the data in `dumpedState` such that we // don't need to burn through RPC requests. diff --git a/yarn-project/yarn.lock b/yarn-project/yarn.lock index 883ffd7cf6f..7c7d75d42af 100644 --- a/yarn-project/yarn.lock +++ b/yarn-project/yarn.lock @@ -284,7 +284,11 @@ __metadata: resolution: "@aztec/canary@workspace:canary" dependencies: "@aztec/aztec.js": "workspace:^" + "@aztec/cli": "workspace:^" "@aztec/end-to-end": "workspace:^" + "@aztec/ethereum": "workspace:^" + "@aztec/l1-artifacts": "workspace:^" + "@aztec/noir-contracts": "workspace:^" "@jest/globals": ^29.5.0 "@rushstack/eslint-patch": ^1.1.4 "@types/jest": ^29.5.0