diff --git a/.gitignore b/.gitignore index 836f3f16ce3..9115ec7782a 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,5 @@ node_modules build/ .idea cmake-build-debug -.bootstrapped \ No newline at end of file +.terraform +.bootstrapped diff --git a/docs/package.json b/docs/package.json index 59441623353..854f13f07f8 100644 --- a/docs/package.json +++ b/docs/package.json @@ -43,7 +43,7 @@ "nodemon": "^3.0.1", "typedoc": "^0.25.1", "typedoc-plugin-markdown": "^3.16.0", - "typescript": "^4.7.2" + "typescript": "^5.0.4" }, "browserslist": { "production": [ diff --git a/docs/yarn.lock b/docs/yarn.lock index 3057a40b1e8..50055128a74 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -8040,10 +8040,10 @@ typedoc@^0.25.1: minimatch "^9.0.3" shiki "^0.14.1" -typescript@^4.7.2: - version "4.9.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.4.tgz#a2a3d2756c079abda241d75f149df9d561091e78" - integrity sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg== +typescript@^5.0.4: + version "5.2.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78" + integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w== ua-parser-js@^0.7.30: version "0.7.32" diff --git a/yarn-project/archiver/src/archiver/archiver.ts b/yarn-project/archiver/src/archiver/archiver.ts index 217df42dab6..f6f25e59c64 100644 --- a/yarn-project/archiver/src/archiver/archiver.ts +++ b/yarn-project/archiver/src/archiver/archiver.ts @@ -103,10 +103,10 @@ export class Archiver implements L2BlockSource, L2LogsSource, ContractDataSource const archiverStore = new MemoryArchiverStore(); const archiver = new Archiver( publicClient, - config.rollupContract, - config.inboxContract, - config.registryContract, - config.contractDeploymentEmitterContract, + config.l1Contracts.rollupAddress, + config.l1Contracts.inboxAddress, + config.l1Contracts.registryAddress, + config.l1Contracts.contractDeploymentEmitterAddress, config.searchStartBlock, archiverStore, config.archiverPollingIntervalMS, diff --git a/yarn-project/archiver/src/archiver/config.ts b/yarn-project/archiver/src/archiver/config.ts index f6604d8c6f2..fbfa3a0ac9f 100644 --- a/yarn-project/archiver/src/archiver/config.ts +++ b/yarn-project/archiver/src/archiver/config.ts @@ -1,5 +1,5 @@ +import { L1ContractAddresses } from '@aztec/ethereum'; import { EthAddress } from '@aztec/foundation/eth-address'; -import { L1Addresses } from '@aztec/types'; /** * There are 2 polling intervals used in this configuration. The first is the archiver polling interval, archiverPollingIntervalMS. @@ -11,7 +11,7 @@ import { L1Addresses } from '@aztec/types'; /** * The archiver configuration. */ -export interface ArchiverConfig extends L1Addresses { +export interface ArchiverConfig { /** * The url of the Ethereum RPC node. */ @@ -36,6 +36,11 @@ export interface ArchiverConfig extends L1Addresses { * Eth block from which we start scanning for L2Blocks. */ searchStartBlock: number; + + /** + * The deployed L1 contract addresses + */ + l1Contracts: L1ContractAddresses; } /** @@ -55,17 +60,23 @@ export function getConfigEnvVars(): ArchiverConfig { INBOX_CONTRACT_ADDRESS, REGISTRY_CONTRACT_ADDRESS, } = process.env; + // Populate the relevant addresses for use by the archiver. + const addresses: L1ContractAddresses = { + rollupAddress: ROLLUP_CONTRACT_ADDRESS ? EthAddress.fromString(ROLLUP_CONTRACT_ADDRESS) : EthAddress.ZERO, + registryAddress: REGISTRY_CONTRACT_ADDRESS ? EthAddress.fromString(REGISTRY_CONTRACT_ADDRESS) : EthAddress.ZERO, + inboxAddress: INBOX_CONTRACT_ADDRESS ? EthAddress.fromString(INBOX_CONTRACT_ADDRESS) : EthAddress.ZERO, + outboxAddress: EthAddress.ZERO, + contractDeploymentEmitterAddress: CONTRACT_DEPLOYMENT_EMITTER_ADDRESS + ? EthAddress.fromString(CONTRACT_DEPLOYMENT_EMITTER_ADDRESS) + : EthAddress.ZERO, + decoderHelperAddress: EthAddress.ZERO, + }; return { rpcUrl: ETHEREUM_HOST || 'http://127.0.0.1:8545/', archiverPollingIntervalMS: ARCHIVER_POLLING_INTERVAL_MS ? +ARCHIVER_POLLING_INTERVAL_MS : 1_000, viemPollingIntervalMS: ARCHIVER_VIEM_POLLING_INTERVAL_MS ? +ARCHIVER_VIEM_POLLING_INTERVAL_MS : 1_000, - rollupContract: ROLLUP_CONTRACT_ADDRESS ? EthAddress.fromString(ROLLUP_CONTRACT_ADDRESS) : EthAddress.ZERO, - registryContract: REGISTRY_CONTRACT_ADDRESS ? EthAddress.fromString(REGISTRY_CONTRACT_ADDRESS) : EthAddress.ZERO, - inboxContract: INBOX_CONTRACT_ADDRESS ? EthAddress.fromString(INBOX_CONTRACT_ADDRESS) : EthAddress.ZERO, - contractDeploymentEmitterContract: CONTRACT_DEPLOYMENT_EMITTER_ADDRESS - ? EthAddress.fromString(CONTRACT_DEPLOYMENT_EMITTER_ADDRESS) - : EthAddress.ZERO, searchStartBlock: SEARCH_START_BLOCK ? +SEARCH_START_BLOCK : 0, apiKey: API_KEY, + l1Contracts: addresses, }; } diff --git a/yarn-project/archiver/src/index.ts b/yarn-project/archiver/src/index.ts index d132e23af90..b327c5f9bb4 100644 --- a/yarn-project/archiver/src/index.ts +++ b/yarn-project/archiver/src/index.ts @@ -17,14 +17,7 @@ const log = createDebugLogger('aztec:archiver'); // eslint-disable-next-line require-await async function main() { const config = getConfigEnvVars(); - const { - rpcUrl, - rollupContract, - inboxContract, - registryContract, - contractDeploymentEmitterContract, - searchStartBlock, - } = config; + const { rpcUrl, l1Contracts, searchStartBlock } = config; const publicClient = createPublicClient({ chain: localhost, @@ -35,10 +28,10 @@ async function main() { const archiver = new Archiver( publicClient, - rollupContract, - inboxContract, - registryContract, - contractDeploymentEmitterContract, + l1Contracts.rollupAddress, + l1Contracts.inboxAddress, + l1Contracts.registryAddress, + l1Contracts.contractDeploymentEmitterAddress, searchStartBlock, archiverStore, ); diff --git a/yarn-project/aztec-node/Dockerfile b/yarn-project/aztec-node/Dockerfile index efb5e939ea5..f93944094e1 100644 --- a/yarn-project/aztec-node/Dockerfile +++ b/yarn-project/aztec-node/Dockerfile @@ -10,6 +10,7 @@ RUN yarn cache clean RUN yarn workspaces focus --production > /dev/null FROM node:18-alpine -COPY --from=builder /usr/src/yarn-project/aztec-node /usr/src/yarn-project/aztec-node +COPY --from=builder /usr/src /usr/src WORKDIR /usr/src/yarn-project/aztec-node -ENTRYPOINT ["yarn"] \ No newline at end of file +ENTRYPOINT ["yarn"] +CMD [ "start" ] \ No newline at end of file diff --git a/yarn-project/aztec-node/package.json b/yarn-project/aztec-node/package.json index 8e785e5b058..85df499f9ba 100644 --- a/yarn-project/aztec-node/package.json +++ b/yarn-project/aztec-node/package.json @@ -4,6 +4,7 @@ "main": "dest/index.js", "type": "module", "exports": "./dest/index.js", + "bin": "./dest/bin/index.js", "typedocOptions": { "entryPoints": [ "./src/index.ts" @@ -12,6 +13,7 @@ "tsconfig": "./tsconfig.json" }, "scripts": { + "start": "node --no-warnings ./dest/bin", "build": "yarn clean && tsc -b", "build:dev": "tsc -b --watch", "clean": "rm -rf ./dest .tsbuildinfo", @@ -33,6 +35,7 @@ "dependencies": { "@aztec/archiver": "workspace:^", "@aztec/circuits.js": "workspace:^", + "@aztec/ethereum": "workspace:^", "@aztec/foundation": "workspace:^", "@aztec/l1-artifacts": "workspace:^", "@aztec/merkle-tree": "workspace:^", @@ -40,6 +43,8 @@ "@aztec/sequencer-client": "workspace:^", "@aztec/types": "workspace:^", "@aztec/world-state": "workspace:^", + "koa": "^2.14.2", + "koa-router": "^12.0.0", "tslib": "^2.4.0" }, "devDependencies": { diff --git a/yarn-project/aztec-node/src/rpc/http_rpc_server.ts b/yarn-project/aztec-node/src/aztec-node/http_rpc_server.ts similarity index 100% rename from yarn-project/aztec-node/src/rpc/http_rpc_server.ts rename to yarn-project/aztec-node/src/aztec-node/http_rpc_server.ts diff --git a/yarn-project/aztec-node/src/aztec-node/server.ts b/yarn-project/aztec-node/src/aztec-node/server.ts index f7feee54aa4..4092bacaf6b 100644 --- a/yarn-project/aztec-node/src/aztec-node/server.ts +++ b/yarn-project/aztec-node/src/aztec-node/server.ts @@ -2,13 +2,13 @@ import { Archiver } from '@aztec/archiver'; import { CONTRACT_TREE_HEIGHT, CircuitsWasm, - EthAddress, Fr, GlobalVariables, HistoricBlockData, L1_TO_L2_MSG_TREE_HEIGHT, PRIVATE_DATA_TREE_HEIGHT, } from '@aztec/circuits.js'; +import { L1ContractAddresses } from '@aztec/ethereum'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { createDebugLogger } from '@aztec/foundation/log'; import { InMemoryTxPool, P2P, createP2PClient } from '@aztec/p2p'; @@ -57,6 +57,7 @@ export const createMemDown = () => (memdown as any)() as MemDown; */ export class AztecNodeService implements AztecNode { constructor( + protected config: AztecNodeConfig, protected p2pClient: P2P, protected blockSource: L2BlockSource, protected encryptedLogsSource: L2LogsSource, @@ -83,7 +84,7 @@ export class AztecNodeService implements AztecNode { // we identify the P2P transaction protocol by using the rollup contract address. // this may well change in future - config.transactionProtocol = `/aztec/tx/${config.rollupContract.toString()}`; + config.transactionProtocol = `/aztec/tx/${config.l1Contracts.rollupAddress.toString()}`; // create the tx pool and the p2p client, which will need the l2 block source const p2pClient = await createP2PClient(config, new InMemoryTxPool(), archiver); @@ -107,6 +108,7 @@ export class AztecNodeService implements AztecNode { archiver, ); return new AztecNodeService( + config, p2pClient, archiver, archiver, @@ -122,6 +124,14 @@ export class AztecNodeService implements AztecNode { ); } + /** + * Method to return the currently deployed L1 contract addresses. + * @returns - The currently deployed L1 contract addresses. + */ + public getL1ContractAddresses(): Promise { + return Promise.resolve(this.config.l1Contracts); + } + /** * Method to determine if the node is ready to accept transactions. * @returns - Flag indicating the readiness for tx submission. @@ -173,18 +183,6 @@ export class AztecNodeService implements AztecNode { return Promise.resolve(this.chainId); } - /** - * Method to fetch the rollup contract address at the base-layer. - * @returns The rollup address. - */ - public getRollupAddress(): Promise { - return this.blockSource.getRollupAddress(); - } - - public getRegistryAddress(): Promise { - return this.blockSource.getRegistryAddress(); - } - /** * Get the extended contract data for this contract. * @param contractAddress - The contract data address. diff --git a/yarn-project/aztec-node/src/bin/index.ts b/yarn-project/aztec-node/src/bin/index.ts new file mode 100644 index 00000000000..6ee1ed4cd78 --- /dev/null +++ b/yarn-project/aztec-node/src/bin/index.ts @@ -0,0 +1,67 @@ +#!/usr/bin/env -S node --no-warnings +import { createDebugLogger } from '@aztec/foundation/log'; + +import http from 'http'; +import Koa from 'koa'; +import Router from 'koa-router'; + +import { AztecNodeConfig, AztecNodeService, getConfigEnvVars, createAztecNodeRpcServer } from '../index.js'; + +const { SERVER_PORT = 8081, API_PREFIX = '' } = process.env; + +const logger = createDebugLogger('aztec:node'); + +/** + * Creates the node from provided config + */ +async function createAndDeployAztecNode() { + const aztecNodeConfig: AztecNodeConfig = { ...getConfigEnvVars() }; + + return await AztecNodeService.createAndSync(aztecNodeConfig); +} + +/** + * Creates a router for helper API endpoints of the Aztec RPC Server. + * @param apiPrefix - The prefix to use for all api requests + * @returns - The router for handling status requests. + */ +export function createStatusRouter(apiPrefix: string) { + const router = new Router({ prefix: `${apiPrefix}` }); + router.get('/status', (ctx: Koa.Context) => { + ctx.status = 200; + }); + return router; +} + +/** + * Create and start a new Aztec Node HTTP Server + */ +async function main() { + logger.info(`Setting up Aztec Node...`); + + const aztecNode = await createAndDeployAztecNode(); + + const shutdown = async () => { + logger.info('Shutting down...'); + await aztecNode.stop(); + process.exit(0); + }; + + process.once('SIGINT', shutdown); + process.once('SIGTERM', shutdown); + + const rpcServer = createAztecNodeRpcServer(aztecNode); + const app = rpcServer.getApp(API_PREFIX); + const apiRouter = createStatusRouter(API_PREFIX); + app.use(apiRouter.routes()); + app.use(apiRouter.allowedMethods()); + + const httpServer = http.createServer(app.callback()); + httpServer.listen(+SERVER_PORT); + logger.info(`Aztec Node JSON-RPC Server listening on port ${SERVER_PORT}`); +} + +main().catch(err => { + logger.error(err); + process.exit(1); +}); diff --git a/yarn-project/aztec-node/src/index.ts b/yarn-project/aztec-node/src/index.ts index 853db6bae96..0cf8b330148 100644 --- a/yarn-project/aztec-node/src/index.ts +++ b/yarn-project/aztec-node/src/index.ts @@ -1,4 +1,3 @@ export * from './aztec-node/config.js'; export * from './aztec-node/server.js'; -export * from './rpc/http_rpc_server.js'; -export * from './rpc/http_rpc_client.js'; +export * from './aztec-node/http_rpc_server.js'; diff --git a/yarn-project/aztec-node/terraform/main.tf b/yarn-project/aztec-node/terraform/main.tf new file mode 100644 index 00000000000..c2518571d3b --- /dev/null +++ b/yarn-project/aztec-node/terraform/main.tf @@ -0,0 +1,247 @@ +terraform { + backend "s3" { + bucket = "aztec-terraform" + region = "eu-west-2" + } + required_providers { + aws = { + source = "hashicorp/aws" + version = "3.74.2" + } + } +} + +# Define provider and region +provider "aws" { + region = "eu-west-2" +} + +data "terraform_remote_state" "setup_iac" { + backend = "s3" + config = { + bucket = "aztec-terraform" + key = "setup/setup-iac" + region = "eu-west-2" + } +} + +data "terraform_remote_state" "aztec2_iac" { + backend = "s3" + config = { + bucket = "aztec-terraform" + key = "aztec2/iac" + region = "eu-west-2" + } +} + + +resource "aws_cloudwatch_log_group" "aztec_node_log_group" { + name = "/fargate/service/${var.DEPLOY_TAG}/aztec-node" + retention_in_days = 14 +} + +resource "aws_service_discovery_service" "aztec-node" { + name = "${var.DEPLOY_TAG}-aztec-node" + + health_check_custom_config { + failure_threshold = 1 + } + + dns_config { + namespace_id = data.terraform_remote_state.setup_iac.outputs.local_service_discovery_id + + dns_records { + ttl = 60 + type = "A" + } + + dns_records { + ttl = 60 + type = "SRV" + } + + routing_policy = "MULTIVALUE" + } + + # Terraform just fails if this resource changes and you have registered instances. + provisioner "local-exec" { + when = destroy + command = "${path.module}/../servicediscovery-drain.sh ${self.id}" + } +} + +# Define task definition and service. +resource "aws_ecs_task_definition" "aztec-node-1" { + family = "${var.DEPLOY_TAG}-aztec-node" + requires_compatibilities = ["FARGATE"] + network_mode = "awsvpc" + cpu = "2048" + memory = "4096" + execution_role_arn = data.terraform_remote_state.setup_iac.outputs.ecs_task_execution_role_arn + task_role_arn = data.terraform_remote_state.aztec2_iac.outputs.cloudwatch_logging_ecs_role_arn + + container_definitions = < { - const [version, chainId, rollupAddress, registryAddress] = await Promise.all([ + const [version, chainId, contractAddresses] = await Promise.all([ this.node.getVersion(), this.node.getChainId(), - this.node.getRollupAddress(), - this.node.getRegistryAddress(), + this.node.getL1ContractAddresses(), ]); - return { + const nodeInfo: NodeInfo = { sandboxVersion: this.sandboxVersion, compatibleNargoVersion: NoirVersion.tag, chainId, protocolVersion: version, - rollupAddress, - registryAddress, + l1ContractAddresses: contractAddresses, }; + return nodeInfo; } /** diff --git a/yarn-project/aztec-rpc/src/aztec_rpc_server/test/aztec_rpc_server.test.ts b/yarn-project/aztec-rpc/src/aztec_rpc_server/test/aztec_rpc_server.test.ts index 99adad75081..09aabfd08ed 100644 --- a/yarn-project/aztec-rpc/src/aztec_rpc_server/test/aztec_rpc_server.test.ts +++ b/yarn-project/aztec-rpc/src/aztec_rpc_server/test/aztec_rpc_server.test.ts @@ -1,11 +1,13 @@ import { Grumpkin } from '@aztec/circuits.js/barretenberg'; +import { L1ContractAddresses } from '@aztec/ethereum'; +import { EthAddress } from '@aztec/foundation/eth-address'; import { TestKeyStore } from '@aztec/key-store'; import { AztecNode, AztecRPC, L2Tx, mockTx } from '@aztec/types'; import { MockProxy, mock } from 'jest-mock-extended'; import { MemoryDB } from '../../database/memory_db.js'; -import { EthAddress, RpcServerConfig } from '../../index.js'; +import { RpcServerConfig } from '../../index.js'; import { AztecRPCServer } from '../aztec_rpc_server.js'; import { aztecRpcTestSuite } from './aztec_rpc_test_suite.js'; @@ -21,7 +23,15 @@ async function createAztecRpcServer(): Promise { node.getBlockNumber.mockResolvedValue(2); node.getVersion.mockResolvedValue(1); node.getChainId.mockResolvedValue(1); - node.getRollupAddress.mockResolvedValue(EthAddress.random()); + const mockedContracts: L1ContractAddresses = { + rollupAddress: EthAddress.random(), + registryAddress: EthAddress.random(), + inboxAddress: EthAddress.random(), + outboxAddress: EthAddress.random(), + contractDeploymentEmitterAddress: EthAddress.random(), + decoderHelperAddress: EthAddress.random(), + }; + node.getL1ContractAddresses.mockResolvedValue(mockedContracts); return new AztecRPCServer(keyStore, node, db, config); } diff --git a/yarn-project/aztec-rpc/src/aztec_rpc_server/test/aztec_rpc_test_suite.ts b/yarn-project/aztec-rpc/src/aztec_rpc_server/test/aztec_rpc_test_suite.ts index 9698c1f08ac..ce612295dfd 100644 --- a/yarn-project/aztec-rpc/src/aztec_rpc_server/test/aztec_rpc_test_suite.ts +++ b/yarn-project/aztec-rpc/src/aztec_rpc_server/test/aztec_rpc_test_suite.ts @@ -135,7 +135,7 @@ export const aztecRpcTestSuite = (testName: string, aztecRpcSetup: () => Promise const nodeInfo = await rpc.getNodeInfo(); expect(typeof nodeInfo.protocolVersion).toEqual('number'); expect(typeof nodeInfo.chainId).toEqual('number'); - expect(nodeInfo.rollupAddress.toString()).toMatch(/0x[a-fA-F0-9]+/); + expect(nodeInfo.l1ContractAddresses.rollupAddress.toString()).toMatch(/0x[a-fA-F0-9]+/); }); // Note: Not testing `isGlobalStateSynchronized`, `isAccountStateSynchronized` and `getSyncStatus` as these methods diff --git a/yarn-project/aztec-rpc/src/bin/index.ts b/yarn-project/aztec-rpc/src/bin/index.ts new file mode 100644 index 00000000000..80584d0a8e6 --- /dev/null +++ b/yarn-project/aztec-rpc/src/bin/index.ts @@ -0,0 +1,39 @@ +#!/usr/bin/env -S node --no-warnings +import { createDebugLogger } from '@aztec/foundation/log'; +import { createAztecNodeRpcClient } from '@aztec/types'; + +import { startHttpRpcServer } from '../aztec_rpc_http/index.js'; +import { createAztecRPCServer } from '../aztec_rpc_server/index.js'; +import { getConfigEnvVars } from '../config/index.js'; + +const { SERVER_PORT = 8080, AZTEC_NODE_RPC_URL = '' } = process.env; + +const logger = createDebugLogger('aztec:rpc_server'); + +/** + * Create and start a new Aztec RCP HTTP Server + */ +async function main() { + logger.info(`Setting up Aztec RPC Server...`); + + const rpcConfig = getConfigEnvVars(); + const nodeRpcClient = createAztecNodeRpcClient(AZTEC_NODE_RPC_URL); + const rpcServer = await createAztecRPCServer(nodeRpcClient, rpcConfig); + + const shutdown = async () => { + logger.info('Shutting down...'); + await rpcServer.stop(); + process.exit(0); + }; + + process.once('SIGINT', shutdown); + process.once('SIGTERM', shutdown); + + startHttpRpcServer(rpcServer, SERVER_PORT); + logger.info(`Aztec RPC Server listening on port ${SERVER_PORT}`); +} + +main().catch(err => { + logger.error(err); + process.exit(1); +}); diff --git a/yarn-project/aztec-rpc/tsconfig.json b/yarn-project/aztec-rpc/tsconfig.json index 8f298d5722d..1190999ce69 100644 --- a/yarn-project/aztec-rpc/tsconfig.json +++ b/yarn-project/aztec-rpc/tsconfig.json @@ -12,6 +12,9 @@ { "path": "../circuits.js" }, + { + "path": "../ethereum" + }, { "path": "../foundation" }, diff --git a/yarn-project/aztec-sandbox/Dockerfile b/yarn-project/aztec-sandbox/Dockerfile index 4bd5ddbdbaa..98c5a6191d0 100644 --- a/yarn-project/aztec-sandbox/Dockerfile +++ b/yarn-project/aztec-sandbox/Dockerfile @@ -13,7 +13,6 @@ RUN if [[ -n "${COMMIT_TAG}" ]]; then \ fi WORKDIR /usr/src/yarn-project/aztec-sandbox -RUN ls RUN if [[ -n "${COMMIT_TAG}" ]]; then \ jq --arg v ${COMMIT_TAG} '.version = $v' package.json > _temp && mv _temp package.json; \ fi diff --git a/yarn-project/aztec-sandbox/src/bin/index.ts b/yarn-project/aztec-sandbox/src/bin/index.ts index 8f906cf874d..4537603afe8 100644 --- a/yarn-project/aztec-sandbox/src/bin/index.ts +++ b/yarn-project/aztec-sandbox/src/bin/index.ts @@ -1,4 +1,5 @@ #!/usr/bin/env -S node --no-warnings +import { startHttpRpcServer } from '@aztec/aztec-rpc'; import { deployInitialSandboxAccounts } from '@aztec/aztec.js'; import { createDebugLogger } from '@aztec/foundation/log'; import { fileURLToPath } from '@aztec/foundation/url'; @@ -9,13 +10,27 @@ import { dirname, resolve } from 'path'; import { setupFileDebugLog } from '../logging.js'; import { createSandbox } from '../sandbox.js'; -import { startHttpRpcServer } from '../server.js'; import { github, splash } from '../splash.js'; const { SERVER_PORT = 8080 } = process.env; const logger = createDebugLogger('aztec:sandbox'); +/** + * Creates the sandbox from provided config and deploys any initial L1 and L2 contracts + */ +async function createAndInitialiseSandbox() { + const { l1Contracts, rpcServer, stop } = await createSandbox(); + logger.info('Setting up test accounts...'); + const accounts = await deployInitialSandboxAccounts(rpcServer); + return { + l1Contracts, + rpcServer, + stop, + accounts, + }; +} + /** * Create and start a new Aztec RCP HTTP Server */ @@ -26,10 +41,7 @@ async function main() { logger.info(`Setting up Aztec Sandbox v${version} (nargo ${NoirVersion.tag}), please stand by...`); - const { l1Contracts, rpcServer, stop } = await createSandbox(); - - logger.info('Setting up test accounts...'); - const accounts = await deployInitialSandboxAccounts(rpcServer); + const { rpcServer, stop, accounts } = await createAndInitialiseSandbox(); const shutdown = async () => { logger.info('Shutting down...'); @@ -40,7 +52,7 @@ async function main() { process.once('SIGINT', shutdown); process.once('SIGTERM', shutdown); - startHttpRpcServer(rpcServer, l1Contracts, SERVER_PORT); + startHttpRpcServer(rpcServer, SERVER_PORT); logger.info(`Aztec Sandbox JSON-RPC Server listening on port ${SERVER_PORT}`); logger.info(`Debug logs will be written to ${logPath}`); const accountStrings = [`Initial Accounts:\n\n`]; diff --git a/yarn-project/aztec-sandbox/src/routes.ts b/yarn-project/aztec-sandbox/src/routes.ts index 43967f3bd82..982fd37677d 100644 --- a/yarn-project/aztec-sandbox/src/routes.ts +++ b/yarn-project/aztec-sandbox/src/routes.ts @@ -1,5 +1,3 @@ -import { DeployL1Contracts } from '@aztec/ethereum'; - import Koa from 'koa'; import Router from 'koa-router'; @@ -8,24 +6,12 @@ import Router from 'koa-router'; * @param aztecNode - An instance of the aztec node. * @param config - The aztec node's configuration variables. */ -export function createApiRouter(l1Contracts: DeployL1Contracts) { +export function createApiRouter() { const router = new Router({ prefix: '/api' }); router.get('/status', (ctx: Koa.Context) => { // TODO: add `status` to Aztec node. ctx.status = 200; }); - router.get('/l1-contract-addresses', (ctx: Koa.Context) => { - ctx.body = { - rollup: l1Contracts.rollupAddress.toString(), - contractDeploymentEmitter: l1Contracts.contractDeploymentEmitterAddress.toString(), - inbox: l1Contracts.inboxAddress.toString(), - outbox: l1Contracts.outboxAddress.toString(), - decoderHelper: l1Contracts.decoderHelperAddress?.toString(), - registry: l1Contracts.registryAddress.toString(), - }; - ctx.status = 200; - }); - return router; } diff --git a/yarn-project/aztec-sandbox/src/sandbox.ts b/yarn-project/aztec-sandbox/src/sandbox.ts index 227cc7f6edb..c3ce6e177f4 100644 --- a/yarn-project/aztec-sandbox/src/sandbox.ts +++ b/yarn-project/aztec-sandbox/src/sandbox.ts @@ -1,11 +1,28 @@ #!/usr/bin/env -S node --no-warnings import { AztecNodeConfig, AztecNodeService, getConfigEnvVars } from '@aztec/aztec-node'; import { createAztecRPCServer, getConfigEnvVars as getRpcConfigEnvVars } from '@aztec/aztec-rpc'; -import { deployL1Contracts } from '@aztec/ethereum'; +import { + DeployL1Contracts, + L1ContractArtifactsForDeployment, + createEthereumChain, + deployL1Contracts, +} from '@aztec/ethereum'; import { createDebugLogger } from '@aztec/foundation/log'; import { retryUntil } from '@aztec/foundation/retry'; +import { + ContractDeploymentEmitterAbi, + ContractDeploymentEmitterBytecode, + InboxAbi, + InboxBytecode, + OutboxAbi, + OutboxBytecode, + RegistryAbi, + RegistryBytecode, + RollupAbi, + RollupBytecode, +} from '@aztec/l1-artifacts'; -import { HDAccount, createPublicClient, http as httpViemTransport } from 'viem'; +import { createPublicClient, http as httpViemTransport } from 'viem'; import { mnemonicToAccount } from 'viem/accounts'; import { foundry } from 'viem/chains'; @@ -18,11 +35,12 @@ const localAnvil = foundry; /** * Helper function that waits for the Ethereum RPC server to respond before deploying L1 contracts. */ -async function waitThenDeploy(rpcUrl: string, hdAccount: HDAccount) { +async function waitThenDeploy(config: AztecNodeConfig, deployFunction: () => Promise) { + const chain = createEthereumChain(config.rpcUrl, config.apiKey); // wait for ETH RPC to respond to a request. const publicClient = createPublicClient({ - chain: foundry, - transport: httpViemTransport(rpcUrl), + chain: chain.chainInfo, + transport: httpViemTransport(chain.rpcUrl), }); const chainID = await retryUntil( async () => { @@ -30,7 +48,7 @@ async function waitThenDeploy(rpcUrl: string, hdAccount: HDAccount) { try { chainId = await publicClient.getChainId(); } catch (err) { - logger.warn(`Failed to connect to Ethereum node at ${rpcUrl}. Retrying...`); + logger.warn(`Failed to connect to Ethereum node at ${chain.rpcUrl}. Retrying...`); } return chainId; }, @@ -40,12 +58,11 @@ async function waitThenDeploy(rpcUrl: string, hdAccount: HDAccount) { ); if (!chainID) { - throw Error(`Ethereum node unresponsive at ${rpcUrl}.`); + throw Error(`Ethereum node unresponsive at ${chain.rpcUrl}.`); } // Deploy L1 contracts - const deployedL1Contracts = await deployL1Contracts(rpcUrl, hdAccount, localAnvil, logger); - return deployedL1Contracts; + return await deployFunction(); } /** Sandbox settings. */ @@ -65,12 +82,38 @@ export async function createSandbox(config: Partial = {}) { const hdAccount = mnemonicToAccount(config.l1Mnemonic ?? MNEMONIC); const privKey = hdAccount.getHdKey().privateKey; - const l1Contracts = await waitThenDeploy(aztecNodeConfig.rpcUrl, hdAccount); + const l1Artifacts: L1ContractArtifactsForDeployment = { + contractDeploymentEmitter: { + contractAbi: ContractDeploymentEmitterAbi, + contractBytecode: ContractDeploymentEmitterBytecode, + }, + registry: { + contractAbi: RegistryAbi, + contractBytecode: RegistryBytecode, + }, + inbox: { + contractAbi: InboxAbi, + contractBytecode: InboxBytecode, + }, + outbox: { + contractAbi: OutboxAbi, + contractBytecode: OutboxBytecode, + }, + rollup: { + contractAbi: RollupAbi, + contractBytecode: RollupBytecode, + }, + }; + + const l1Contracts = await waitThenDeploy(aztecNodeConfig, () => + deployL1Contracts(aztecNodeConfig.rpcUrl, hdAccount, localAnvil, logger, l1Artifacts), + ); aztecNodeConfig.publisherPrivateKey = `0x${Buffer.from(privKey!).toString('hex')}`; - aztecNodeConfig.rollupContract = l1Contracts.rollupAddress; - aztecNodeConfig.contractDeploymentEmitterContract = l1Contracts.contractDeploymentEmitterAddress; - aztecNodeConfig.inboxContract = l1Contracts.inboxAddress; - aztecNodeConfig.registryContract = l1Contracts.registryAddress; + aztecNodeConfig.l1Contracts.rollupAddress = l1Contracts.l1ContractAddresses.rollupAddress; + aztecNodeConfig.l1Contracts.contractDeploymentEmitterAddress = + l1Contracts.l1ContractAddresses.contractDeploymentEmitterAddress; + aztecNodeConfig.l1Contracts.inboxAddress = l1Contracts.l1ContractAddresses.inboxAddress; + aztecNodeConfig.l1Contracts.registryAddress = l1Contracts.l1ContractAddresses.registryAddress; const node = await AztecNodeService.createAndSync(aztecNodeConfig); const rpcServer = await createAztecRPCServer(node, rpcConfig); diff --git a/yarn-project/aztec-sandbox/src/server.ts b/yarn-project/aztec-sandbox/src/server.ts index e749c4cc79c..0e37b1c91a0 100644 --- a/yarn-project/aztec-sandbox/src/server.ts +++ b/yarn-project/aztec-sandbox/src/server.ts @@ -1,5 +1,4 @@ import { getHttpRpcServer } from '@aztec/aztec-rpc'; -import { DeployL1Contracts } from '@aztec/ethereum'; import { AztecRPC } from '@aztec/types'; import http from 'http'; @@ -9,19 +8,14 @@ import { createApiRouter } from './routes.js'; /** * Creates an http server that forwards calls to the rpc server and starts it on the given port. * @param aztecRpcServer - RPC server that answers queries to the created HTTP server. - * @param deployedL1Contracts - Info on L1 deployed contracts. * @param port - Port to listen in. * @returns A running http server. */ -export function startHttpRpcServer( - aztecRpcServer: AztecRPC, - deployedL1Contracts: DeployL1Contracts, - port: string | number, -): http.Server { +export function startHttpRpcServer(aztecRpcServer: AztecRPC, port: string | number): http.Server { const rpcServer = getHttpRpcServer(aztecRpcServer); const app = rpcServer.getApp(); - const apiRouter = createApiRouter(deployedL1Contracts); + const apiRouter = createApiRouter(); app.use(apiRouter.routes()); app.use(apiRouter.allowedMethods()); diff --git a/yarn-project/aztec.js/package.json b/yarn-project/aztec.js/package.json index 12d26f8484b..cf560b1b957 100644 --- a/yarn-project/aztec.js/package.json +++ b/yarn-project/aztec.js/package.json @@ -39,6 +39,7 @@ }, "dependencies": { "@aztec/circuits.js": "workspace:^", + "@aztec/ethereum": "workspace:^", "@aztec/foundation": "workspace:^", "@aztec/types": "workspace:^", "lodash.every": "^4.6.0", diff --git a/yarn-project/aztec.js/src/contract/contract.test.ts b/yarn-project/aztec.js/src/contract/contract.test.ts index a095b316b57..6afe155e32e 100644 --- a/yarn-project/aztec.js/src/contract/contract.test.ts +++ b/yarn-project/aztec.js/src/contract/contract.test.ts @@ -1,4 +1,5 @@ import { AztecAddress, CompleteAddress, EthAddress } from '@aztec/circuits.js'; +import { L1ContractAddresses } from '@aztec/ethereum'; import { ABIParameterVisibility, ContractAbi, FunctionType } from '@aztec/foundation/abi'; import { DeployedContract, @@ -28,13 +29,20 @@ describe('Contract Class', () => { const mockTxHash = { type: 'TxHash' } as any as TxHash; const mockTxReceipt = { type: 'TxReceipt' } as any as TxReceipt; const mockViewResultValue = 1; + const l1Addresses: L1ContractAddresses = { + rollupAddress: EthAddress.random(), + registryAddress: EthAddress.random(), + inboxAddress: EthAddress.random(), + outboxAddress: EthAddress.random(), + contractDeploymentEmitterAddress: EthAddress.random(), + decoderHelperAddress: EthAddress.random(), + }; const mockNodeInfo: NodeInfo = { sandboxVersion: 'vx.x.x', compatibleNargoVersion: 'vx.x.x-aztec.x', - protocolVersion: 1, - chainId: 2, - rollupAddress: EthAddress.random(), - registryAddress: EthAddress.random(), + chainId: 1, + protocolVersion: 2, + l1ContractAddresses: l1Addresses, }; const defaultAbi: ContractAbi = { diff --git a/yarn-project/aztec.js/src/utils/cheat_codes.ts b/yarn-project/aztec.js/src/utils/cheat_codes.ts index fc3fe96c080..dc0dfee94fb 100644 --- a/yarn-project/aztec.js/src/utils/cheat_codes.ts +++ b/yarn-project/aztec.js/src/utils/cheat_codes.ts @@ -257,7 +257,7 @@ export class AztecCheatCodes { * @param to - The timestamp to set the next block to (must be greater than current time) */ public async warp(to: number): Promise { - const rollupContract = (await this.aztecRpc.getNodeInfo()).rollupAddress; + const rollupContract = (await this.aztecRpc.getNodeInfo()).l1ContractAddresses.rollupAddress; await this.eth.setNextBlockTimestamp(to); // also store this time on the rollup contract (slot 1 tracks `lastBlockTs`). // This is because when the sequencer executes public functions, it uses the timestamp stored in the rollup contract. diff --git a/yarn-project/aztec.js/tsconfig.json b/yarn-project/aztec.js/tsconfig.json index 01c876235ce..7d0bb1110ba 100644 --- a/yarn-project/aztec.js/tsconfig.json +++ b/yarn-project/aztec.js/tsconfig.json @@ -9,6 +9,9 @@ { "path": "../circuits.js" }, + { + "path": "../ethereum" + }, { "path": "../foundation" }, diff --git a/yarn-project/cli/package.json b/yarn-project/cli/package.json index 8a9dce35fdf..0f680becf60 100644 --- a/yarn-project/cli/package.json +++ b/yarn-project/cli/package.json @@ -37,9 +37,11 @@ "@aztec/aztec.js": "workspace:^", "@aztec/ethereum": "workspace:^", "@aztec/foundation": "workspace:^", + "@aztec/l1-artifacts": "workspace:^", "@aztec/noir-compiler": "workspace:^", "@aztec/noir-contracts": "workspace:^", "@aztec/types": "workspace:^", + "@libp2p/peer-id-factory": "^3.0.4", "commander": "^9.0.0", "jszip": "^3.10.1", "lodash.startcase": "^4.4.0", diff --git a/yarn-project/cli/src/index.ts b/yarn-project/cli/src/index.ts index 1945cd3217b..6e048412cb7 100644 --- a/yarn-project/cli/src/index.ts +++ b/yarn-project/cli/src/index.ts @@ -16,9 +16,9 @@ import { fileURLToPath } from '@aztec/foundation/url'; import { compileContract, generateNoirInterface, generateTypescriptInterface } from '@aztec/noir-compiler/cli'; import { CompleteAddress, ContractData, L2BlockL2Logs, TxHash } from '@aztec/types'; +import { createSecp256k1PeerId } from '@libp2p/peer-id-factory'; import { Command } from 'commander'; import { readFileSync } from 'fs'; -import startCase from 'lodash.startcase'; import { dirname, resolve } from 'path'; import { mnemonicToAccount } from 'viem/accounts'; @@ -75,20 +75,19 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command { 'test test test test test test test test test test test junk', ) .action(async options => { - const { rollupAddress, registryAddress, inboxAddress, outboxAddress, contractDeploymentEmitterAddress } = - await deployAztecContracts( - options.rpcUrl, - options.apiKey ?? '', - options.privateKey, - options.mnemonic, - debugLogger, - ); + const { l1ContractAddresses } = await deployAztecContracts( + options.rpcUrl, + options.apiKey ?? '', + options.privateKey, + options.mnemonic, + debugLogger, + ); log('\n'); - log(`Rollup Address: ${rollupAddress.toString()}`); - log(`Registry Address: ${registryAddress.toString()}`); - log(`L1 -> L2 Inbox Address: ${inboxAddress.toString()}`); - log(`L2 -> L1 Outbox address: ${outboxAddress.toString()}`); - log(`Contract Deployment Emitter Address: ${contractDeploymentEmitterAddress.toString()}`); + log(`Rollup Address: ${l1ContractAddresses.rollupAddress.toString()}`); + log(`Registry Address: ${l1ContractAddresses.registryAddress.toString()}`); + log(`L1 -> L2 Inbox Address: ${l1ContractAddresses.inboxAddress.toString()}`); + log(`L2 -> L1 Outbox address: ${l1ContractAddresses.outboxAddress.toString()}`); + log(`Contract Deployment Emitter Address: ${l1ContractAddresses.contractDeploymentEmitterAddress.toString()}`); log('\n'); }); @@ -118,6 +117,17 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command { log(`\nPrivate Key: ${privKey}\nPublic Key: ${publicKey.toString()}\n`); }); + program + .command('generate-p2p-private-key') + .summary('Generates a LibP2P peer private key.') + .description('Generates a private key that can be used for running a node on a LibP2P network.') + .action(async () => { + const peerId = await createSecp256k1PeerId(); + const exportedPeerId = Buffer.from(peerId.privateKey!).toString('hex'); + log(`Private key: ${exportedPeerId}`); + log(`Peer Id: ${peerId}`); + }); + program .command('create-account') .description( @@ -501,7 +511,11 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command { const client = await createCompatibleClient(options.rpcUrl, debugLogger); const info = await client.getNodeInfo(); log(`\nNode Info:\n`); - Object.entries(info).map(([key, value]) => log(`${startCase(key)}: ${value}`)); + log(`Sandbox Version: ${info.sandboxVersion}\n`); + log(`Compatible Nargo Version: ${info.compatibleNargoVersion}\n`); + log(`Chain Id: ${info.chainId}\n`); + log(`Protocol Version: ${info.protocolVersion}\n`); + log(`Rollup Address: ${info.l1ContractAddresses.rollupAddress.toString()}`); }); program diff --git a/yarn-project/cli/src/utils.ts b/yarn-project/cli/src/utils.ts index aa8dc514ef6..7bb19a4f8db 100644 --- a/yarn-project/cli/src/utils.ts +++ b/yarn-project/cli/src/utils.ts @@ -1,7 +1,19 @@ import { AztecAddress, AztecRPC, Fr } from '@aztec/aztec.js'; -import { createEthereumChain, deployL1Contracts } from '@aztec/ethereum'; +import { L1ContractArtifactsForDeployment, createEthereumChain, deployL1Contracts } from '@aztec/ethereum'; import { ContractAbi } from '@aztec/foundation/abi'; import { DebugLogger, LogFn } from '@aztec/foundation/log'; +import { + ContractDeploymentEmitterAbi, + ContractDeploymentEmitterBytecode, + InboxAbi, + InboxBytecode, + OutboxAbi, + OutboxBytecode, + RegistryAbi, + RegistryBytecode, + RollupAbi, + RollupBytecode, +} from '@aztec/l1-artifacts'; import { InvalidArgumentError } from 'commander'; import fs from 'fs'; @@ -47,7 +59,29 @@ export async function deployAztecContracts( ) { const account = !privateKey ? mnemonicToAccount(mnemonic!) : privateKeyToAccount(`0x${privateKey}`); const chain = createEthereumChain(rpcUrl, apiKey); - return await deployL1Contracts(chain.rpcUrl, account, chain.chainInfo, debugLogger); + const l1Artifacts: L1ContractArtifactsForDeployment = { + contractDeploymentEmitter: { + contractAbi: ContractDeploymentEmitterAbi, + contractBytecode: ContractDeploymentEmitterBytecode, + }, + registry: { + contractAbi: RegistryAbi, + contractBytecode: RegistryBytecode, + }, + inbox: { + contractAbi: InboxAbi, + contractBytecode: InboxBytecode, + }, + outbox: { + contractAbi: OutboxAbi, + contractBytecode: OutboxBytecode, + }, + rollup: { + contractAbi: RollupAbi, + contractBytecode: RollupBytecode, + }, + }; + return await deployL1Contracts(chain.rpcUrl, account, chain.chainInfo, debugLogger, l1Artifacts); } /** diff --git a/yarn-project/cli/tsconfig.json b/yarn-project/cli/tsconfig.json index a654a1611c8..7bd5491149a 100644 --- a/yarn-project/cli/tsconfig.json +++ b/yarn-project/cli/tsconfig.json @@ -15,6 +15,9 @@ { "path": "../foundation" }, + { + "path": "../l1-artifacts" + }, { "path": "../noir-compiler" }, diff --git a/yarn-project/end-to-end/src/e2e_cheat_codes.test.ts b/yarn-project/end-to-end/src/e2e_cheat_codes.test.ts index a01c24e10eb..891a41d9feb 100644 --- a/yarn-project/end-to-end/src/e2e_cheat_codes.test.ts +++ b/yarn-project/end-to-end/src/e2e_cheat_codes.test.ts @@ -24,7 +24,7 @@ describe('e2e_cheat_codes', () => { walletClient = deployL1ContractsValues.walletClient; publicClient = deployL1ContractsValues.publicClient; - rollupAddress = deployL1ContractsValues.rollupAddress; + rollupAddress = deployL1ContractsValues.l1ContractAddresses.rollupAddress; }, 100_000); afterAll(() => teardown()); 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 112748fe75b..19d4d44a9d1 100644 --- a/yarn-project/end-to-end/src/e2e_cli.test.ts +++ b/yarn-project/end-to-end/src/e2e_cli.test.ts @@ -17,9 +17,8 @@ let aztecRpcServer: AztecRPC; const testSetup = async () => { const context = await e2eSetup(2); debug(`Environment set up`); - const { deployL1ContractsValues } = context; ({ aztecNode, aztecRpcServer } = context); - http = startHttpRpcServer(aztecRpcServer, deployL1ContractsValues, HTTP_PORT); + http = startHttpRpcServer(aztecRpcServer, HTTP_PORT); debug(`HTTP RPC server started in port ${HTTP_PORT}`); return aztecRpcServer; }; diff --git a/yarn-project/end-to-end/src/e2e_p2p_network.test.ts b/yarn-project/end-to-end/src/e2e_p2p_network.test.ts index d29197e3411..dc650816ade 100644 --- a/yarn-project/end-to-end/src/e2e_p2p_network.test.ts +++ b/yarn-project/end-to-end/src/e2e_p2p_network.test.ts @@ -10,7 +10,7 @@ import { AztecAddress, CompleteAddress, Fr, PublicKey, getContractDeploymentInfo import { Grumpkin } from '@aztec/circuits.js/barretenberg'; import { DebugLogger } from '@aztec/foundation/log'; import { TestContractAbi } from '@aztec/noir-contracts/artifacts'; -import { BootstrapNode, P2PConfig, createLibP2PPeerId, exportLibP2PPeerIdToString } from '@aztec/p2p'; +import { BootstrapNode, P2PConfig, createLibP2PPeerId } from '@aztec/p2p'; import { TxStatus } from '@aztec/types'; import { setup } from './fixtures/utils.js'; @@ -85,8 +85,8 @@ describe('e2e_p2p_network', () => { tcpListenIp: '0.0.0.0', announceHostname: '127.0.0.1', announcePort: BOOT_NODE_TCP_PORT, - peerIdPrivateKey: exportLibP2PPeerIdToString(peerId), - serverMode: true, + peerIdPrivateKey: Buffer.from(peerId.privateKey!).toString('hex'), + serverMode: false, minPeerCount: 10, maxPeerCount: 100, diff --git a/yarn-project/end-to-end/src/e2e_sandbox_example.test.ts b/yarn-project/end-to-end/src/e2e_sandbox_example.test.ts index 7f0b77d7aa9..84f72c805ca 100644 --- a/yarn-project/end-to-end/src/e2e_sandbox_example.test.ts +++ b/yarn-project/end-to-end/src/e2e_sandbox_example.test.ts @@ -33,7 +33,7 @@ describe('e2e_sandbox_example', () => { expect(typeof nodeInfo.protocolVersion).toBe('number'); expect(typeof nodeInfo.chainId).toBe('number'); - expect(typeof nodeInfo.rollupAddress).toBe('object'); + expect(typeof nodeInfo.l1ContractAddresses.rollupAddress).toBe('object'); // For the sandbox quickstart we just want to show them preloaded accounts (since it is a quickstart) // We show creation of accounts in a later test diff --git a/yarn-project/end-to-end/src/fixtures/cross_chain_test_harness.ts b/yarn-project/end-to-end/src/fixtures/cross_chain_test_harness.ts index e34244ade3f..ac0e4938aa3 100644 --- a/yarn-project/end-to-end/src/fixtures/cross_chain_test_harness.ts +++ b/yarn-project/end-to-end/src/fixtures/cross_chain_test_harness.ts @@ -36,7 +36,7 @@ export class CrossChainTestHarness { const [owner, receiver] = accounts; const outbox = getContract({ - address: deployL1ContractsValues.outboxAddress.toString(), + address: deployL1ContractsValues.l1ContractAddresses.outboxAddress!.toString(), abi: OutboxAbi, publicClient, }); @@ -47,7 +47,7 @@ export class CrossChainTestHarness { wallet, walletClient, publicClient, - deployL1ContractsValues!.registryAddress, + deployL1ContractsValues!.l1ContractAddresses.registryAddress!, owner.address, underlyingERC20Address, ); diff --git a/yarn-project/end-to-end/src/fixtures/utils.ts b/yarn-project/end-to-end/src/fixtures/utils.ts index a4fd4fabdad..9caea63c96a 100644 --- a/yarn-project/end-to-end/src/fixtures/utils.ts +++ b/yarn-project/end-to-end/src/fixtures/utils.ts @@ -1,10 +1,5 @@ import { AztecNodeConfig, AztecNodeService, getConfigEnvVars } from '@aztec/aztec-node'; -import { - AztecRPCServer, - RpcServerConfig, - createAztecRPCServer, - getConfigEnvVars as getRpcConfigEnvVars, -} from '@aztec/aztec-rpc'; +import { AztecRPCServer, createAztecRPCServer, getConfigEnvVars as getRpcConfigEnvVars } from '@aztec/aztec-rpc'; import { AccountWallet, AztecAddress, @@ -15,16 +10,37 @@ import { Wallet, createAccounts, createAztecRpcClient as createJsonRpcClient, - getL1ContractAddresses, getSandboxAccountsWallets, } from '@aztec/aztec.js'; import { CircuitsWasm, GeneratorIndex } from '@aztec/circuits.js'; import { pedersenPlookupCompressWithHashIndex } from '@aztec/circuits.js/barretenberg'; -import { DeployL1Contracts, deployL1Contract, deployL1Contracts } from '@aztec/ethereum'; +import { + DeployL1Contracts, + L1ContractArtifactsForDeployment, + deployL1Contract, + deployL1Contracts, +} from '@aztec/ethereum'; import { Fr } from '@aztec/foundation/fields'; import { DebugLogger, createDebugLogger } from '@aztec/foundation/log'; import { retryUntil } from '@aztec/foundation/retry'; -import { PortalERC20Abi, PortalERC20Bytecode, TokenPortalAbi, TokenPortalBytecode } from '@aztec/l1-artifacts'; +import { + ContractDeploymentEmitterAbi, + ContractDeploymentEmitterBytecode, + DecoderHelperAbi, + DecoderHelperBytecode, + InboxAbi, + InboxBytecode, + OutboxAbi, + OutboxBytecode, + PortalERC20Abi, + PortalERC20Bytecode, + RegistryAbi, + RegistryBytecode, + RollupAbi, + RollupBytecode, + TokenPortalAbi, + TokenPortalBytecode, +} from '@aztec/l1-artifacts'; import { NonNativeTokenContract, TokenBridgeContract, TokenContract } from '@aztec/noir-contracts/types'; import { AztecRPC, L2BlockL2Logs, LogType, TxStatus } from '@aztec/types'; @@ -33,6 +49,7 @@ import { Chain, HDAccount, HttpTransport, + PrivateKeyAccount, PublicClient, WalletClient, createPublicClient, @@ -71,50 +88,41 @@ const createAztecNode = async ( return await AztecNodeService.createAndSync(nodeConfig); }; -const createRpcServer = async ( - rpcConfig: RpcServerConfig, - aztecNode: AztecNodeService | undefined, +export const setupL1Contracts = async ( + l1RpcUrl: string, + account: HDAccount | PrivateKeyAccount, logger: DebugLogger, - useLogSuffix?: boolean | string, -): Promise => { - if (SANDBOX_URL) { - logger(`Creating JSON RPC client to remote host ${SANDBOX_URL}`); - const jsonClient = createJsonRpcClient(SANDBOX_URL); - await waitForRPCServer(jsonClient, logger); - logger('JSON RPC client connected to RPC Server'); - return jsonClient; - } else if (!aztecNode) { - throw new Error('Invalid aztec node when creating RPC server'); - } - return createAztecRPCServer(aztecNode, rpcConfig, {}, useLogSuffix); -}; - -const setupL1Contracts = async (l1RpcUrl: string, account: HDAccount, logger: DebugLogger) => { - if (SANDBOX_URL) { - logger(`Retrieving contract addresses from ${SANDBOX_URL}`); - const l1Contracts = await getL1ContractAddresses(SANDBOX_URL); - - const walletClient = createWalletClient({ - account, - chain: localAnvil, - transport: http(l1RpcUrl), - }); - const publicClient = createPublicClient({ - chain: localAnvil, - transport: http(l1RpcUrl), - }); - return { - rollupAddress: l1Contracts.rollup, - registryAddress: l1Contracts.registry, - inboxAddress: l1Contracts.inbox, - outboxAddress: l1Contracts.outbox, - contractDeploymentEmitterAddress: l1Contracts.contractDeploymentEmitter, - decoderHelperAddress: l1Contracts.decoderHelper, - walletClient, - publicClient, + deployDecoderHelper = false, +) => { + const l1Artifacts: L1ContractArtifactsForDeployment = { + contractDeploymentEmitter: { + contractAbi: ContractDeploymentEmitterAbi, + contractBytecode: ContractDeploymentEmitterBytecode, + }, + registry: { + contractAbi: RegistryAbi, + contractBytecode: RegistryBytecode, + }, + inbox: { + contractAbi: InboxAbi, + contractBytecode: InboxBytecode, + }, + outbox: { + contractAbi: OutboxAbi, + contractBytecode: OutboxBytecode, + }, + rollup: { + contractAbi: RollupAbi, + contractBytecode: RollupBytecode, + }, + }; + if (deployDecoderHelper) { + l1Artifacts.decoderHelper = { + contractAbi: DecoderHelperAbi, + contractBytecode: DecoderHelperBytecode, }; } - return await deployL1Contracts(l1RpcUrl, account, localAnvil, logger); + return await deployL1Contracts(l1RpcUrl, account, localAnvil, logger, l1Artifacts); }; /** @@ -128,7 +136,7 @@ const setupL1Contracts = async (l1RpcUrl: string, account: HDAccount, logger: De */ export async function setupAztecRPCServer( numberOfAccounts: number, - aztecNode: AztecNodeService | undefined, + aztecNode: AztecNodeService, logger = getLogger(), useLogSuffix = false, ): Promise<{ @@ -150,19 +158,9 @@ export async function setupAztecRPCServer( logger: DebugLogger; }> { const rpcConfig = getRpcConfigEnvVars(); - const rpc = await createRpcServer(rpcConfig, aztecNode, logger, useLogSuffix); - - const createWallets = () => { - if (!SANDBOX_URL) { - logger('RPC server created, deploying new accounts...'); - return createAccounts(rpc, numberOfAccounts); - } else { - logger('RPC server created, constructing wallets from initial sandbox accounts...'); - return getSandboxAccountsWallets(rpc); - } - }; + const rpc = await createAztecRPCServer(aztecNode, rpcConfig, {}, useLogSuffix); - const wallets = await createWallets(); + const wallets = await createAccounts(rpc, numberOfAccounts); return { aztecRpcServer: rpc!, @@ -172,6 +170,54 @@ export async function setupAztecRPCServer( }; } +/** + * Function to setup the test against a running sandbox. + * @param account - The account for use in create viem wallets. + * @param config - The aztec Node Configuration + * @param logger - The logger to be used + * @returns RPC Client, viwm wallets, contract addreses etc. + */ +async function setupWithSandbox(account: Account, config: AztecNodeConfig, logger: DebugLogger) { + // we are setting up against the sandbox, l1 contracts are already deployed + logger(`Creating JSON RPC client to remote host ${SANDBOX_URL}`); + const jsonClient = createJsonRpcClient(SANDBOX_URL); + await waitForRPCServer(jsonClient, logger); + logger('JSON RPC client connected to RPC Server'); + logger(`Retrieving contract addresses from ${SANDBOX_URL}`); + const l1Contracts = (await jsonClient.getNodeInfo()).l1ContractAddresses; + logger('RPC server created, constructing wallets from initial sandbox accounts...'); + const wallets = await getSandboxAccountsWallets(jsonClient); + + const walletClient = createWalletClient({ + account, + chain: localAnvil, + transport: http(config.rpcUrl), + }); + const publicClient = createPublicClient({ + chain: localAnvil, + transport: http(config.rpcUrl), + }); + const deployL1ContractsValues: DeployL1Contracts = { + l1ContractAddresses: l1Contracts, + walletClient, + publicClient, + }; + const cheatCodes = await CheatCodes.create(config.rpcUrl, jsonClient!); + const teardown = () => Promise.resolve(); + return { + aztecNode: undefined, + aztecRpcServer: jsonClient, + deployL1ContractsValues, + accounts: await jsonClient!.getRegisteredAccounts(), + config, + wallet: wallets[0], + wallets, + logger, + cheatCodes, + teardown, + }; +} + /** * Sets up the environment for the end-to-end tests. * @param numberOfAccounts - The number of new accounts to be created once the RPC server is initiated. @@ -231,19 +277,25 @@ export async function setup( const logger = getLogger(); const hdAccount = mnemonicToAccount(MNEMONIC); + if (SANDBOX_URL) { + // we are setting up against the sandbox, l1 contracts are already deployed + return await setupWithSandbox(hdAccount, config, logger); + } + const deployL1ContractsValues = await setupL1Contracts(config.rpcUrl, hdAccount, logger); const privKeyRaw = hdAccount.getHdKey().privateKey; const publisherPrivKey = privKeyRaw === null ? null : Buffer.from(privKeyRaw); config.publisherPrivateKey = `0x${publisherPrivKey!.toString('hex')}`; - config.rollupContract = deployL1ContractsValues.rollupAddress; - config.contractDeploymentEmitterContract = deployL1ContractsValues.contractDeploymentEmitterAddress; - config.inboxContract = deployL1ContractsValues.inboxAddress; - config.registryContract = deployL1ContractsValues.registryAddress; + config.l1Contracts.rollupAddress = deployL1ContractsValues.l1ContractAddresses.rollupAddress; + config.l1Contracts.registryAddress = deployL1ContractsValues.l1ContractAddresses.registryAddress; + config.l1Contracts.contractDeploymentEmitterAddress = + deployL1ContractsValues.l1ContractAddresses.contractDeploymentEmitterAddress; + config.l1Contracts.inboxAddress = deployL1ContractsValues.l1ContractAddresses.inboxAddress; const aztecNode = await createAztecNode(config, logger); - const { aztecRpcServer, accounts, wallets } = await setupAztecRPCServer(numberOfAccounts, aztecNode, logger); + const { aztecRpcServer, accounts, wallets } = await setupAztecRPCServer(numberOfAccounts, aztecNode!, logger); const cheatCodes = await CheatCodes.create(config.rpcUrl, aztecRpcServer!); diff --git a/yarn-project/end-to-end/src/integration_archiver_l1_to_l2.test.ts b/yarn-project/end-to-end/src/integration_archiver_l1_to_l2.test.ts index 871cfcd455f..2c021dba910 100644 --- a/yarn-project/end-to-end/src/integration_archiver_l1_to_l2.test.ts +++ b/yarn-project/end-to-end/src/integration_archiver_l1_to_l2.test.ts @@ -50,7 +50,7 @@ describe('archiver integration with l1 to l2 messages', () => { wallet, walletClient, publicClient, - deployL1ContractsValues!.registryAddress, + deployL1ContractsValues!.l1ContractAddresses.registryAddress!, initialBalance, owner, ); diff --git a/yarn-project/end-to-end/src/integration_l1_publisher.test.ts b/yarn-project/end-to-end/src/integration_l1_publisher.test.ts index 13bcd08e760..7a70dff9c38 100644 --- a/yarn-project/end-to-end/src/integration_l1_publisher.test.ts +++ b/yarn-project/end-to-end/src/integration_l1_publisher.test.ts @@ -13,8 +13,6 @@ import { range, } from '@aztec/circuits.js'; import { fr, makeNewContractData, makeProof } from '@aztec/circuits.js/factories'; -import { deployL1Contracts } from '@aztec/ethereum'; -import { EthAddress } from '@aztec/foundation/eth-address'; import { Fr } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; import { to2Fields } from '@aztec/foundation/serialize'; @@ -49,7 +47,7 @@ import { } from 'viem'; import { PrivateKeyAccount, privateKeyToAccount } from 'viem/accounts'; -import { localAnvil } from './fixtures/fixtures.js'; +import { setupL1Contracts } from './fixtures/utils.js'; // Accounts 4 and 5 of Anvil default startup with mnemonic: 'test test test test test test test test test test test junk' const sequencerPK = '0x47e179ec197488593b187f80a00eb0da91f1b9d0b13f8733639f19c30a34926a'; @@ -68,8 +66,6 @@ describe('L1Publisher integration', () => { let rollupAddress: Address; let inboxAddress: Address; let outboxAddress: Address; - let registryAddress: Address; - let contractDeploymentEmitterAddress: Address; let decoderHelperAddress: Address; let rollup: GetContractReturnType>; @@ -93,23 +89,16 @@ describe('L1Publisher integration', () => { beforeEach(async () => { deployerAccount = privateKeyToAccount(deployerPK); const { - rollupAddress: rollupAddress_, - inboxAddress: inboxAddress_, - outboxAddress: outboxAddress_, - registryAddress: registryAddress_, - contractDeploymentEmitterAddress: contractDeploymentEmitterAddress_, - decoderHelperAddress: decoderHelperAddress_, - publicClient: publicClient_, + l1ContractAddresses, walletClient, - } = await deployL1Contracts(config.rpcUrl, deployerAccount, localAnvil, logger, true); + publicClient: publicClient_, + } = await setupL1Contracts(config.rpcUrl, deployerAccount, logger, true); publicClient = publicClient_; - rollupAddress = getAddress(rollupAddress_.toString()); - inboxAddress = getAddress(inboxAddress_.toString()); - outboxAddress = getAddress(outboxAddress_.toString()); - registryAddress = getAddress(registryAddress_.toString()); - contractDeploymentEmitterAddress = getAddress(contractDeploymentEmitterAddress_.toString()); - decoderHelperAddress = getAddress(decoderHelperAddress_!.toString()); + rollupAddress = getAddress(l1ContractAddresses.rollupAddress.toString()); + inboxAddress = getAddress(l1ContractAddresses.inboxAddress.toString()); + outboxAddress = getAddress(l1ContractAddresses.outboxAddress.toString()); + decoderHelperAddress = getAddress(l1ContractAddresses.decoderHelperAddress.toString()); // Set up contract instances rollup = getContract({ @@ -146,10 +135,7 @@ describe('L1Publisher integration', () => { rpcUrl: config.rpcUrl, apiKey: '', requiredConfirmations: 1, - rollupContract: EthAddress.fromString(rollupAddress), - inboxContract: EthAddress.fromString(inboxAddress), - registryContract: EthAddress.fromString(registryAddress), - contractDeploymentEmitterContract: EthAddress.fromString(contractDeploymentEmitterAddress), + l1Contracts: l1ContractAddresses, publisherPrivateKey: sequencerPK, l1BlockPublishRetryIntervalMS: 100, }); 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 bb9fce4f8cb..b1d220dceca 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 @@ -109,7 +109,7 @@ describe.skip('uniswap_trade_on_l1_from_l2', () => { await uniswapL2Contract.attach(uniswapPortalAddress); await uniswapPortal.write.initialize( - [deployL1ContractsValues!.registryAddress.toString(), uniswapL2Contract.address.toString()], + [deployL1ContractsValues!.l1ContractAddresses.registryAddress!.toString(), uniswapL2Contract.address.toString()], {} as any, ); diff --git a/yarn-project/ethereum/Dockerfile b/yarn-project/ethereum/Dockerfile index 206d5034cd6..35123be37db 100644 --- a/yarn-project/ethereum/Dockerfile +++ b/yarn-project/ethereum/Dockerfile @@ -14,4 +14,4 @@ RUN yarn workspaces focus --production > /dev/null FROM node:18-alpine COPY --from=builder /usr/src/ /usr/src/ WORKDIR /usr/src/yarn-project/ethereum -ENTRYPOINT ["yarn", "start"] \ No newline at end of file +ENTRYPOINT ["yarn"] \ No newline at end of file diff --git a/yarn-project/ethereum/package.json b/yarn-project/ethereum/package.json index 90e6f2ee7c1..26fec484fa2 100644 --- a/yarn-project/ethereum/package.json +++ b/yarn-project/ethereum/package.json @@ -25,7 +25,6 @@ ], "dependencies": { "@aztec/foundation": "workspace:^", - "@aztec/l1-artifacts": "workspace:^", "dotenv": "^16.0.3", "tslib": "^2.4.0", "viem": "^1.2.5" diff --git a/yarn-project/ethereum/src/deploy_l1_contracts.ts b/yarn-project/ethereum/src/deploy_l1_contracts.ts index 4a8a7998e03..49933e2477c 100644 --- a/yarn-project/ethereum/src/deploy_l1_contracts.ts +++ b/yarn-project/ethereum/src/deploy_l1_contracts.ts @@ -1,19 +1,5 @@ import { EthAddress } from '@aztec/foundation/eth-address'; import { DebugLogger } from '@aztec/foundation/log'; -import { - ContractDeploymentEmitterAbi, - ContractDeploymentEmitterBytecode, - DecoderHelperAbi, - DecoderHelperBytecode, - InboxAbi, - InboxBytecode, - OutboxAbi, - OutboxBytecode, - RegistryAbi, - RegistryBytecode, - RollupAbi, - RollupBytecode, -} from '@aztec/l1-artifacts'; import type { Abi, Narrow } from 'abitype'; import { @@ -31,6 +17,8 @@ import { } from 'viem'; import { HDAccount, PrivateKeyAccount } from 'viem/accounts'; +import { L1ContractAddresses } from './l1_contract_addresses.js'; + /** * Return type of the deployL1Contract function. */ @@ -43,31 +31,56 @@ export type DeployL1Contracts = { * Public Client Type. */ publicClient: PublicClient; + + /** + * The currently deployed l1 contract addresses + */ + l1ContractAddresses: L1ContractAddresses; +}; + +/** + * Contract artifacts + */ +export interface ContractArtifacts { + /** + * The conttract abi. + */ + contractAbi: Narrow; + /** + * The contract bytecode + */ + contractBytecode: Hex; +} + +/** + * All L1 Contract Artifacts for deployment + */ +export interface L1ContractArtifactsForDeployment { /** - * Rollup Address. + * Contract deployment emitter artifacts */ - rollupAddress: EthAddress; + contractDeploymentEmitter: ContractArtifacts; /** - * Registry Address. + * Decoder contract artifacts */ - registryAddress: EthAddress; + decoderHelper?: ContractArtifacts; /** - * Inbox Address. + * Inbox contract artifacts */ - inboxAddress: EthAddress; + inbox: ContractArtifacts; /** - * Outbox Address. + * Outbox contract artifacts */ - outboxAddress: EthAddress; + outbox: ContractArtifacts; /** - * Data Emitter Address. + * Registry contract artifacts */ - contractDeploymentEmitterAddress: EthAddress; + registry: ContractArtifacts; /** - * Decoder Helper Address. + * Rollup contract artifacts */ - decoderHelperAddress?: EthAddress; -}; + rollup: ContractArtifacts; +} /** * Deploys the aztec L1 contracts; Rollup, Contract Deployment Emitter & (optionally) Decoder Helper. @@ -75,7 +88,7 @@ export type DeployL1Contracts = { * @param account - Private Key or HD Account that will deploy the contracts. * @param chain - The chain instance to deploy to. * @param logger - A logger object. - * @param deployDecoderHelper - Boolean, whether to deploy the decoder helper or not. + * @param contractsToDeploy - The set of L1 artifacts to be deployed * @returns A list of ETH addresses of the deployed contracts. */ export const deployL1Contracts = async ( @@ -83,7 +96,7 @@ export const deployL1Contracts = async ( account: HDAccount | PrivateKeyAccount, chain: Chain, logger: DebugLogger, - deployDecoderHelper = false, + contractsToDeploy: L1ContractArtifactsForDeployment, ): Promise => { logger('Deploying contracts...'); @@ -97,28 +110,45 @@ export const deployL1Contracts = async ( transport: http(rpcUrl), }); - const registryAddress = await deployL1Contract(walletClient, publicClient, RegistryAbi, RegistryBytecode); + const registryAddress = await deployL1Contract( + walletClient, + publicClient, + contractsToDeploy.registry.contractAbi, + contractsToDeploy.registry.contractBytecode, + ); logger(`Deployed Registry at ${registryAddress}`); - const inboxAddress = await deployL1Contract(walletClient, publicClient, InboxAbi, InboxBytecode, [ - getAddress(registryAddress.toString()), - ]); + const inboxAddress = await deployL1Contract( + walletClient, + publicClient, + contractsToDeploy.inbox.contractAbi, + contractsToDeploy.inbox.contractBytecode, + [getAddress(registryAddress.toString())], + ); logger(`Deployed Inbox at ${inboxAddress}`); - const outboxAddress = await deployL1Contract(walletClient, publicClient, OutboxAbi, OutboxBytecode, [ - getAddress(registryAddress.toString()), - ]); + const outboxAddress = await deployL1Contract( + walletClient, + publicClient, + contractsToDeploy.outbox.contractAbi, + contractsToDeploy.outbox.contractBytecode, + [getAddress(registryAddress.toString())], + ); logger(`Deployed Outbox at ${outboxAddress}`); - const rollupAddress = await deployL1Contract(walletClient, publicClient, RollupAbi, RollupBytecode, [ - getAddress(registryAddress.toString()), - ]); + const rollupAddress = await deployL1Contract( + walletClient, + publicClient, + contractsToDeploy.rollup.contractAbi, + contractsToDeploy.rollup.contractBytecode, + [getAddress(registryAddress.toString())], + ); logger(`Deployed Rollup at ${rollupAddress}`); // We need to call a function on the registry to set the various contract addresses. const registryContract = getContract({ address: getAddress(registryAddress.toString()), - abi: RegistryAbi, + abi: contractsToDeploy.registry.contractAbi, publicClient, walletClient, }); @@ -130,26 +160,35 @@ export const deployL1Contracts = async ( const contractDeploymentEmitterAddress = await deployL1Contract( walletClient, publicClient, - ContractDeploymentEmitterAbi, - ContractDeploymentEmitterBytecode, + contractsToDeploy.contractDeploymentEmitter.contractAbi, + contractsToDeploy.contractDeploymentEmitter.contractBytecode, ); logger(`Deployed contract deployment emitter at ${contractDeploymentEmitterAddress}`); let decoderHelperAddress: EthAddress | undefined; - if (deployDecoderHelper) { - decoderHelperAddress = await deployL1Contract(walletClient, publicClient, DecoderHelperAbi, DecoderHelperBytecode); + if (contractsToDeploy.decoderHelper) { + decoderHelperAddress = await deployL1Contract( + walletClient, + publicClient, + contractsToDeploy.decoderHelper.contractAbi, + contractsToDeploy.decoderHelper.contractBytecode, + ); logger(`Deployed DecoderHelper at ${decoderHelperAddress}`); } - return { - walletClient, - publicClient, + const l1Contracts: L1ContractAddresses = { rollupAddress, registryAddress, inboxAddress, outboxAddress, contractDeploymentEmitterAddress, - decoderHelperAddress, + decoderHelperAddress: decoderHelperAddress ?? EthAddress.ZERO, + }; + + return { + walletClient, + publicClient, + l1ContractAddresses: l1Contracts, }; }; diff --git a/yarn-project/ethereum/src/index.ts b/yarn-project/ethereum/src/index.ts index 6279349059c..c8edddb8dde 100644 --- a/yarn-project/ethereum/src/index.ts +++ b/yarn-project/ethereum/src/index.ts @@ -5,6 +5,7 @@ import { createTestnetChain } from './testnet.js'; export * from './testnet.js'; export * from './deploy_l1_contracts.js'; +export * from './l1_contract_addresses.js'; /** * Helper function to create an instance of Aztec Chain from an rpc url and api key. diff --git a/yarn-project/ethereum/src/l1_contract_addresses.ts b/yarn-project/ethereum/src/l1_contract_addresses.ts new file mode 100644 index 00000000000..a5021698775 --- /dev/null +++ b/yarn-project/ethereum/src/l1_contract_addresses.ts @@ -0,0 +1,31 @@ +import { EthAddress } from '@aztec/foundation/eth-address'; + +/** + * Provides the directory of current L1 contract addresses + */ +export interface L1ContractAddresses { + /** + * Rollup Address. + */ + rollupAddress: EthAddress; + /** + * Registry Address. + */ + registryAddress: EthAddress; + /** + * Inbox Address. + */ + inboxAddress: EthAddress; + /** + * Outbox Address. + */ + outboxAddress: EthAddress; + /** + * Data Emitter Address. + */ + contractDeploymentEmitterAddress: EthAddress; + /** + * Decoder Helper Address. + */ + decoderHelperAddress: EthAddress; +} diff --git a/yarn-project/ethereum/tsconfig.json b/yarn-project/ethereum/tsconfig.json index b12e902b946..e92b3fa2562 100644 --- a/yarn-project/ethereum/tsconfig.json +++ b/yarn-project/ethereum/tsconfig.json @@ -9,9 +9,6 @@ "references": [ { "path": "../foundation" - }, - { - "path": "../l1-artifacts" } ] } diff --git a/yarn-project/foundation/package.json b/yarn-project/foundation/package.json index 3e8e058f4be..59e7f903efb 100644 --- a/yarn-project/foundation/package.json +++ b/yarn-project/foundation/package.json @@ -58,7 +58,7 @@ "debug": "^4.3.4", "detect-node": "^2.1.0", "hash.js": "^1.1.7", - "koa": "^2.14.1", + "koa": "^2.14.2", "koa-bodyparser": "^4.4.0", "koa-compress": "^5.1.0", "koa-router": "^12.0.0", diff --git a/yarn-project/p2p-bootstrap/Dockerfile b/yarn-project/p2p-bootstrap/Dockerfile index da22a6c8198..a2c114481f1 100644 --- a/yarn-project/p2p-bootstrap/Dockerfile +++ b/yarn-project/p2p-bootstrap/Dockerfile @@ -14,4 +14,5 @@ RUN yarn workspaces focus --production > /dev/null FROM node:18-alpine COPY --from=builder /usr/src/ /usr/src/ WORKDIR /usr/src/yarn-project/p2p-bootstrap -ENTRYPOINT ["yarn", "start"] \ No newline at end of file +ENTRYPOINT ["yarn"] +CMD ["start"] \ No newline at end of file diff --git a/yarn-project/p2p/src/bootstrap/bootstrap.ts b/yarn-project/p2p/src/bootstrap/bootstrap.ts index 5c02976f1e2..e57e9596263 100644 --- a/yarn-project/p2p/src/bootstrap/bootstrap.ts +++ b/yarn-project/p2p/src/bootstrap/bootstrap.ts @@ -5,7 +5,6 @@ import { yamux } from '@chainsafe/libp2p-yamux'; import type { ServiceMap } from '@libp2p/interface-libp2p'; import { kadDHT } from '@libp2p/kad-dht'; import { mplex } from '@libp2p/mplex'; -import { createFromProtobuf } from '@libp2p/peer-id-factory'; import { tcp } from '@libp2p/tcp'; import { Libp2p, Libp2pOptions, ServiceFactoryMap, createLibp2p } from 'libp2p'; import { identifyService } from 'libp2p/identify'; @@ -29,9 +28,7 @@ export class BootstrapNode { public async start(config: P2PConfig) { const { peerIdPrivateKey, tcpListenIp, tcpListenPort, announceHostname, announcePort, minPeerCount, maxPeerCount } = config; - const peerId = peerIdPrivateKey - ? await createFromProtobuf(Buffer.from(peerIdPrivateKey, 'hex')) - : await createLibP2PPeerId(); + const peerId = await createLibP2PPeerId(peerIdPrivateKey); this.logger( `Starting bootstrap node ${peerId} on ${tcpListenIp}:${tcpListenPort} announced at ${announceHostname}:${announcePort}`, ); @@ -41,7 +38,7 @@ export class BootstrapNode { peerId, addresses: { listen: [`/ip4/${tcpListenIp}/tcp/${tcpListenPort}`], - announce: [`/ip4/${announceHostname}/tcp/${announcePort ?? tcpListenPort}`], + announce: announceHostname ? [`/ip4/${announceHostname}/tcp/${announcePort ?? tcpListenPort}`] : [], }, transports: [tcp()], streamMuxers: [yamux(), mplex()], diff --git a/yarn-project/p2p/src/service/libp2p_service.ts b/yarn-project/p2p/src/service/libp2p_service.ts index ca2e5f4de8a..83cd580e320 100644 --- a/yarn-project/p2p/src/service/libp2p_service.ts +++ b/yarn-project/p2p/src/service/libp2p_service.ts @@ -10,7 +10,7 @@ import { PeerId } from '@libp2p/interface-peer-id'; import { IncomingStreamData } from '@libp2p/interface/stream-handler'; import { DualKadDHT, kadDHT } from '@libp2p/kad-dht'; import { mplex } from '@libp2p/mplex'; -import { createEd25519PeerId, createFromProtobuf, exportToProtobuf } from '@libp2p/peer-id-factory'; +import { createFromJSON, createSecp256k1PeerId, exportToProtobuf } from '@libp2p/peer-id-factory'; import { tcp } from '@libp2p/tcp'; import { pipe } from 'it-pipe'; import { Libp2p, Libp2pOptions, ServiceFactoryMap, createLibp2p } from 'libp2p'; @@ -35,11 +35,19 @@ import { const INITIAL_PEER_REFRESH_INTERVAL = 20000; /** - * Create a libp2p peer ID. + * Create a libp2p peer ID from the private key if provided, otherwise creates a new random ID. + * @param privateKey - Optional peer ID private key as hex string * @returns The peer ID. */ -export async function createLibP2PPeerId() { - return await createEd25519PeerId(); +export async function createLibP2PPeerId(privateKey?: string) { + if (!privateKey) { + return await createSecp256k1PeerId(); + } + const base64 = Buffer.from(privateKey, 'hex').toString('base64'); + return await createFromJSON({ + id: '', + privKey: base64, + }); } /** @@ -141,10 +149,9 @@ export class LibP2PService implements P2PService { serverMode, minPeerCount, maxPeerCount, + peerIdPrivateKey, } = config; - const peerId = config.peerIdPrivateKey - ? await createFromProtobuf(Buffer.from(config.peerIdPrivateKey, 'hex')) - : await createLibP2PPeerId(); + const peerId = await createLibP2PPeerId(peerIdPrivateKey); const opts: Libp2pOptions = { start: false, diff --git a/yarn-project/sequencer-client/src/config.ts b/yarn-project/sequencer-client/src/config.ts index 3a5540f97b3..5a75ff6980b 100644 --- a/yarn-project/sequencer-client/src/config.ts +++ b/yarn-project/sequencer-client/src/config.ts @@ -1,3 +1,4 @@ +import { L1ContractAddresses } from '@aztec/ethereum'; import { EthAddress } from '@aztec/foundation/eth-address'; import { GlobalReaderConfig } from './global_variable_builder/index.js'; @@ -35,6 +36,17 @@ export function getConfigEnvVars(): SequencerClientConfig { ? SEQ_PUBLISHER_PRIVATE_KEY.replace('0x', '') : '0000000000000000000000000000000000000000000000000000000000000000' }`; + // Populate the relevant addresses for use by the sequencer + const addresses: L1ContractAddresses = { + rollupAddress: ROLLUP_CONTRACT_ADDRESS ? EthAddress.fromString(ROLLUP_CONTRACT_ADDRESS) : EthAddress.ZERO, + registryAddress: REGISTRY_CONTRACT_ADDRESS ? EthAddress.fromString(REGISTRY_CONTRACT_ADDRESS) : EthAddress.ZERO, + inboxAddress: INBOX_CONTRACT_ADDRESS ? EthAddress.fromString(INBOX_CONTRACT_ADDRESS) : EthAddress.ZERO, + outboxAddress: EthAddress.ZERO, + contractDeploymentEmitterAddress: CONTRACT_DEPLOYMENT_EMITTER_ADDRESS + ? EthAddress.fromString(CONTRACT_DEPLOYMENT_EMITTER_ADDRESS) + : EthAddress.ZERO, + decoderHelperAddress: EthAddress.ZERO, + }; return { rpcUrl: ETHEREUM_HOST ? ETHEREUM_HOST : '', @@ -44,12 +56,7 @@ export function getConfigEnvVars(): SequencerClientConfig { requiredConfirmations: SEQ_REQUIRED_CONFS ? +SEQ_REQUIRED_CONFS : 1, l1BlockPublishRetryIntervalMS: SEQ_PUBLISH_RETRY_INTERVAL_MS ? +SEQ_PUBLISH_RETRY_INTERVAL_MS : 1_000, transactionPollingIntervalMS: SEQ_TX_POLLING_INTERVAL_MS ? +SEQ_TX_POLLING_INTERVAL_MS : 1_000, - rollupContract: ROLLUP_CONTRACT_ADDRESS ? EthAddress.fromString(ROLLUP_CONTRACT_ADDRESS) : EthAddress.ZERO, - inboxContract: INBOX_CONTRACT_ADDRESS ? EthAddress.fromString(INBOX_CONTRACT_ADDRESS) : EthAddress.ZERO, - registryContract: REGISTRY_CONTRACT_ADDRESS ? EthAddress.fromString(REGISTRY_CONTRACT_ADDRESS) : EthAddress.ZERO, - contractDeploymentEmitterContract: CONTRACT_DEPLOYMENT_EMITTER_ADDRESS - ? EthAddress.fromString(CONTRACT_DEPLOYMENT_EMITTER_ADDRESS) - : EthAddress.ZERO, + l1Contracts: addresses, publisherPrivateKey, maxTxsPerBlock: SEQ_MAX_TX_PER_BLOCK ? +SEQ_MAX_TX_PER_BLOCK : 32, minTxsPerBlock: SEQ_MIN_TX_PER_BLOCK ? +SEQ_MIN_TX_PER_BLOCK : 1, diff --git a/yarn-project/sequencer-client/src/global_variable_builder/config.ts b/yarn-project/sequencer-client/src/global_variable_builder/config.ts index 909d3d32b05..2884374561a 100644 --- a/yarn-project/sequencer-client/src/global_variable_builder/config.ts +++ b/yarn-project/sequencer-client/src/global_variable_builder/config.ts @@ -1,13 +1,9 @@ -import { EthAddress } from '@aztec/circuits.js'; +import { L1ContractAddresses } from '@aztec/ethereum'; /** * Configuration of the L1GlobalReader. */ export interface GlobalReaderConfig { - /** - * Rollup contract address. - */ - rollupContract: EthAddress; /** * The RPC Url of the ethereum host. */ @@ -16,4 +12,9 @@ export interface GlobalReaderConfig { * The API key of the ethereum host. */ apiKey?: string; + + /** + * The deployed l1 contract addresses + */ + l1Contracts: L1ContractAddresses; } diff --git a/yarn-project/sequencer-client/src/global_variable_builder/viem-reader.ts b/yarn-project/sequencer-client/src/global_variable_builder/viem-reader.ts index e351db0c09d..ae0617d9fb3 100644 --- a/yarn-project/sequencer-client/src/global_variable_builder/viem-reader.ts +++ b/yarn-project/sequencer-client/src/global_variable_builder/viem-reader.ts @@ -23,7 +23,7 @@ export class ViemReader implements L1GlobalReader { private publicClient: PublicClient; constructor(config: GlobalReaderConfig) { - const { rpcUrl, apiKey, rollupContract: rollupContractAddress } = config; + const { rpcUrl, apiKey, l1Contracts } = config; const chain = createEthereumChain(rpcUrl, apiKey); @@ -33,7 +33,7 @@ export class ViemReader implements L1GlobalReader { }); this.rollupContract = getContract({ - address: getAddress(rollupContractAddress.toString()), + address: getAddress(l1Contracts.rollupAddress.toString()), abi: RollupAbi, publicClient: this.publicClient, }); diff --git a/yarn-project/sequencer-client/src/publisher/config.ts b/yarn-project/sequencer-client/src/publisher/config.ts index 5ec4cfde76c..96ad07bd6f1 100644 --- a/yarn-project/sequencer-client/src/publisher/config.ts +++ b/yarn-project/sequencer-client/src/publisher/config.ts @@ -1,9 +1,9 @@ -import { L1Addresses } from '@aztec/types'; +import { L1ContractAddresses } from '@aztec/ethereum'; /** * The configuration of the rollup transaction publisher. */ -export interface TxSenderConfig extends L1Addresses { +export interface TxSenderConfig { /** * The private key to be used by the publisher. */ @@ -23,6 +23,11 @@ export interface TxSenderConfig extends L1Addresses { * The number of confirmations required. */ requiredConfirmations: number; + + /** + * The deployed l1 contract addresses + */ + l1Contracts: L1ContractAddresses; } /** diff --git a/yarn-project/sequencer-client/src/publisher/viem-tx-sender.ts b/yarn-project/sequencer-client/src/publisher/viem-tx-sender.ts index d9e112e8d0a..2e087b723fe 100644 --- a/yarn-project/sequencer-client/src/publisher/viem-tx-sender.ts +++ b/yarn-project/sequencer-client/src/publisher/viem-tx-sender.ts @@ -41,13 +41,7 @@ export class ViemTxSender implements L1PublisherTxSender { private account: PrivateKeyAccount; constructor(config: TxSenderConfig) { - const { - rpcUrl, - apiKey, - publisherPrivateKey, - rollupContract: rollupContractAddress, - contractDeploymentEmitterContract: contractDeploymentEmitterContractAddress, - } = config; + const { rpcUrl, apiKey, publisherPrivateKey, l1Contracts } = config; const chain = createEthereumChain(rpcUrl, apiKey); this.account = privateKeyToAccount(publisherPrivateKey); const walletClient = createWalletClient({ @@ -62,13 +56,13 @@ export class ViemTxSender implements L1PublisherTxSender { }); this.rollupContract = getContract({ - address: getAddress(rollupContractAddress.toString()), + address: getAddress(l1Contracts.rollupAddress.toString()), abi: RollupAbi, publicClient: this.publicClient, walletClient, }); this.contractDeploymentEmitterContract = getContract({ - address: getAddress(contractDeploymentEmitterContractAddress.toString()), + address: getAddress(l1Contracts.contractDeploymentEmitterAddress.toString()), abi: ContractDeploymentEmitterAbi, publicClient: this.publicClient, walletClient, diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.ts index 5f2f4c2b1e8..47ceb34799b 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.ts @@ -32,8 +32,6 @@ export class Sequencer { private minTxsPerBLock = 1; private lastPublishedBlock = 0; private state = SequencerState.STOPPED; - private chainId: Fr; - private version: Fr; constructor( private publisher: L1Publisher, @@ -54,8 +52,6 @@ export class Sequencer { if (config.minTxsPerBlock) { this.minTxsPerBLock = config.minTxsPerBlock; } - this.chainId = new Fr(config.chainId); - this.version = new Fr(config.version); } /** diff --git a/yarn-project/types/package.json b/yarn-project/types/package.json index 78977f0c5f4..78fa4e4fda9 100644 --- a/yarn-project/types/package.json +++ b/yarn-project/types/package.json @@ -31,6 +31,7 @@ }, "dependencies": { "@aztec/circuits.js": "workspace:^", + "@aztec/ethereum": "workspace:^", "@aztec/foundation": "workspace:^", "browserify-cipher": "^1.0.1", "lodash.clonedeep": "^4.5.0", diff --git a/yarn-project/aztec-node/src/rpc/http_rpc_client.ts b/yarn-project/types/src/aztec_node/rpc/http_rpc_client.ts similarity index 100% rename from yarn-project/aztec-node/src/rpc/http_rpc_client.ts rename to yarn-project/types/src/aztec_node/rpc/http_rpc_client.ts diff --git a/yarn-project/types/src/aztec_node/rpc/index.ts b/yarn-project/types/src/aztec_node/rpc/index.ts new file mode 100644 index 00000000000..e8ecf164fef --- /dev/null +++ b/yarn-project/types/src/aztec_node/rpc/index.ts @@ -0,0 +1 @@ +export * from './http_rpc_client.js'; diff --git a/yarn-project/types/src/index.ts b/yarn-project/types/src/index.ts index c9714153628..9d41e4dcb67 100644 --- a/yarn-project/types/src/index.ts +++ b/yarn-project/types/src/index.ts @@ -4,7 +4,6 @@ export * from './contract_database.js'; export * from './contract_data.js'; export * from './function_call.js'; export * from './keys/index.js'; -export * from './l1_addresses.js'; export * from './l1_to_l2_message.js'; export * from './l2_block.js'; export * from './l2_block_context.js'; @@ -22,5 +21,6 @@ export * from './packed_arguments.js'; export * from './interfaces/index.js'; export * from './sibling_path.js'; export * from './auth_witness.js'; +export * from './aztec_node/rpc/index.js'; export * from '@aztec/circuits.js/types'; export { CompleteAddress } from '@aztec/circuits.js'; diff --git a/yarn-project/types/src/interfaces/aztec-node.ts b/yarn-project/types/src/interfaces/aztec-node.ts index de41c581c6a..c5184e7e920 100644 --- a/yarn-project/types/src/interfaces/aztec-node.ts +++ b/yarn-project/types/src/interfaces/aztec-node.ts @@ -1,4 +1,5 @@ -import { EthAddress, HistoricBlockData } from '@aztec/circuits.js'; +import { HistoricBlockData } from '@aztec/circuits.js'; +import { L1ContractAddresses } from '@aztec/ethereum'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; @@ -67,16 +68,10 @@ export interface AztecNode getChainId(): Promise; /** - * Method to fetch the rollup contract address at the base-layer. - * @returns The rollup address. + * Method to fetch the currently deployed l1 contract addresses. + * @returns The deployed contract addresses. */ - getRollupAddress(): Promise; - - /** - * Method to fetch the registry contract address at the base-layer. - * @returns The registry address. - */ - getRegistryAddress(): Promise; + getL1ContractAddresses(): Promise; /** * Get the extended contract data for this contract. diff --git a/yarn-project/types/src/interfaces/node-info.ts b/yarn-project/types/src/interfaces/node-info.ts index 6c10d6b5ef8..3aaef041da8 100644 --- a/yarn-project/types/src/interfaces/node-info.ts +++ b/yarn-project/types/src/interfaces/node-info.ts @@ -1,9 +1,9 @@ -import { EthAddress } from '@aztec/circuits.js'; +import { L1ContractAddresses } from '@aztec/ethereum'; /** * Provides basic information about the running node. */ -export type NodeInfo = { +export interface NodeInfo { /** * Version as tracked in the aztec-packages repository. */ @@ -21,11 +21,7 @@ export type NodeInfo = { */ protocolVersion: number; /** - * The rollup contract address + * The deployed l1 contract addresses */ - rollupAddress: EthAddress; - /** - * The registry contract address - */ - registryAddress: EthAddress; -}; + l1ContractAddresses: L1ContractAddresses; +} diff --git a/yarn-project/types/src/l1_addresses.ts b/yarn-project/types/src/l1_addresses.ts deleted file mode 100644 index a85fb0f889a..00000000000 --- a/yarn-project/types/src/l1_addresses.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { EthAddress } from '@aztec/foundation/eth-address'; - -/** - * Rollup contract addresses. - */ -export interface L1Addresses { - /** - * Rollup contract address. - */ - rollupContract: EthAddress; - - /** - * Inbox contract address. - */ - inboxContract: EthAddress; - - /** - * Registry contract address. - */ - registryContract: EthAddress; - - /** - * ContractDeploymentEmitter contract address. - */ - contractDeploymentEmitterContract: EthAddress; -} diff --git a/yarn-project/types/tsconfig.json b/yarn-project/types/tsconfig.json index 82aa8cf4ccf..e7053342b34 100644 --- a/yarn-project/types/tsconfig.json +++ b/yarn-project/types/tsconfig.json @@ -9,6 +9,9 @@ { "path": "../circuits.js" }, + { + "path": "../ethereum" + }, { "path": "../foundation" } diff --git a/yarn-project/yarn.lock b/yarn-project/yarn.lock index 9252fc38ac7..30f0e303e5e 100644 --- a/yarn-project/yarn.lock +++ b/yarn-project/yarn.lock @@ -120,6 +120,7 @@ __metadata: dependencies: "@aztec/archiver": "workspace:^" "@aztec/circuits.js": "workspace:^" + "@aztec/ethereum": "workspace:^" "@aztec/foundation": "workspace:^" "@aztec/l1-artifacts": "workspace:^" "@aztec/merkle-tree": "workspace:^" @@ -134,10 +135,14 @@ __metadata: "@types/memdown": ^3.0.0 "@types/node": ^18.7.23 jest: ^29.5.0 + koa: ^2.14.2 + koa-router: ^12.0.0 ts-jest: ^29.1.0 ts-node: ^10.9.1 tslib: ^2.4.0 typescript: ^5.0.4 + bin: + aztec-node: ./dest/bin/index.js languageName: unknown linkType: soft @@ -147,6 +152,7 @@ __metadata: dependencies: "@aztec/acir-simulator": "workspace:^" "@aztec/circuits.js": "workspace:^" + "@aztec/ethereum": "workspace:^" "@aztec/foundation": "workspace:^" "@aztec/key-store": "workspace:^" "@aztec/noir-compiler": "workspace:^" @@ -160,6 +166,8 @@ __metadata: "@types/node": ^18.7.23 jest: ^29.5.0 jest-mock-extended: ^3.0.3 + koa: ^2.14.2 + koa-router: ^12.0.0 lodash.omit: ^4.5.0 lodash.partition: ^4.6.0 lodash.times: ^4.3.2 @@ -169,6 +177,8 @@ __metadata: tslib: ^2.4.0 typescript: ^5.0.4 viem: ^1.2.5 + bin: + aztec-rpc: ./dest/bin/index.js languageName: unknown linkType: soft @@ -228,6 +238,7 @@ __metadata: resolution: "@aztec/aztec.js@workspace:aztec.js" dependencies: "@aztec/circuits.js": "workspace:^" + "@aztec/ethereum": "workspace:^" "@aztec/foundation": "workspace:^" "@aztec/types": "workspace:^" "@jest/globals": ^29.5.0 @@ -339,10 +350,12 @@ __metadata: "@aztec/aztec.js": "workspace:^" "@aztec/ethereum": "workspace:^" "@aztec/foundation": "workspace:^" + "@aztec/l1-artifacts": "workspace:^" "@aztec/noir-compiler": "workspace:^" "@aztec/noir-contracts": "workspace:^" "@aztec/types": "workspace:^" "@jest/globals": ^29.5.0 + "@libp2p/peer-id-factory": ^3.0.4 "@rushstack/eslint-patch": ^1.1.4 "@types/jest": ^29.5.0 "@types/lodash.startcase": ^4.4.7 @@ -428,7 +441,6 @@ __metadata: resolution: "@aztec/ethereum@workspace:ethereum" dependencies: "@aztec/foundation": "workspace:^" - "@aztec/l1-artifacts": "workspace:^" "@jest/globals": ^29.5.0 "@rushstack/eslint-patch": ^1.1.4 "@types/jest": ^29.5.0 @@ -477,7 +489,7 @@ __metadata: eslint-plugin-tsdoc: ^0.2.17 hash.js: ^1.1.7 jest: ^29.5.0 - koa: ^2.14.1 + koa: ^2.14.2 koa-bodyparser: ^4.4.0 koa-compress: ^5.1.0 koa-router: ^12.0.0 @@ -730,6 +742,7 @@ __metadata: resolution: "@aztec/types@workspace:types" dependencies: "@aztec/circuits.js": "workspace:^" + "@aztec/ethereum": "workspace:^" "@aztec/foundation": "workspace:^" "@jest/globals": ^29.5.0 "@rushstack/eslint-patch": ^1.1.4 @@ -2678,6 +2691,22 @@ __metadata: languageName: node linkType: hard +"@libp2p/crypto@npm:^2.0.4": + version: 2.0.4 + resolution: "@libp2p/crypto@npm:2.0.4" + dependencies: + "@libp2p/interface": ^0.1.2 + "@noble/curves": ^1.1.0 + "@noble/hashes": ^1.3.1 + multiformats: ^12.0.1 + node-forge: ^1.1.0 + protons-runtime: ^5.0.0 + uint8arraylist: ^2.4.3 + uint8arrays: ^4.0.6 + checksum: 1e0a0e8006e9ca7caaec16ce94d193063749fc7f62a7b3d0b4469915e2837c380987baa400a9f35ee13c23783f8317f8bc58b8ed647a5b4bf55635a2a909ae97 + languageName: node + linkType: hard + "@libp2p/interface-connection@npm:^5.0.0": version: 5.1.1 resolution: "@libp2p/interface-connection@npm:5.1.1" @@ -3004,6 +3033,21 @@ __metadata: languageName: node linkType: hard +"@libp2p/peer-id-factory@npm:^3.0.4": + version: 3.0.4 + resolution: "@libp2p/peer-id-factory@npm:3.0.4" + dependencies: + "@libp2p/crypto": ^2.0.4 + "@libp2p/interface": ^0.1.2 + "@libp2p/peer-id": ^3.0.2 + multiformats: ^12.0.1 + protons-runtime: ^5.0.0 + uint8arraylist: ^2.4.3 + uint8arrays: ^4.0.6 + checksum: 40c534029bfa8d9b98119ee2c0ce3c0c91bcf7280028e7ba8bfe4da2a90de53014791d75c8d1400877919f748918704276b6e3337c5128975842c0593464fda9 + languageName: node + linkType: hard + "@libp2p/peer-id@npm:^3.0.0, @libp2p/peer-id@npm:^3.0.2": version: 3.0.2 resolution: "@libp2p/peer-id@npm:3.0.2" @@ -13076,7 +13120,7 @@ __metadata: languageName: node linkType: hard -"koa@npm:^2.14.1, koa@npm:^2.14.2": +"koa@npm:^2.14.2": version: 2.14.2 resolution: "koa@npm:2.14.2" dependencies: