diff --git a/yarn-project/.gitignore b/yarn-project/.gitignore index 3d5566cf6bb..8d62059b17e 100644 --- a/yarn-project/.gitignore +++ b/yarn-project/.gitignore @@ -43,6 +43,7 @@ scripts/tmp noir-contracts.js/src noir-contracts.js/artifacts/ noir-contracts.js/codegenCache.json +types/fixtures/*.json .yarn/* !.yarn/patches diff --git a/yarn-project/types/package.json b/yarn-project/types/package.json index 4bdfbc0801e..724ff7853dd 100644 --- a/yarn-project/types/package.json +++ b/yarn-project/types/package.json @@ -13,16 +13,19 @@ "./noir": "./dest/noir/index.js" }, "scripts": { - "build": "yarn clean && tsc -b", + "build": "yarn clean && yarn generate && tsc -b", "build:dev": "tsc -b --watch", "clean": "rm -rf ./dest .tsbuildinfo", "formatting": "run -T prettier --check ./src && run -T eslint ./src", "formatting:fix": "run -T eslint --fix ./src && run -T prettier -w ./src", "test:light": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --passWithNoTests", - "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --passWithNoTests" + "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --passWithNoTests", + "generate": "yarn generate:noir-contracts", + "generate:noir-contracts": "./scripts/copy-contracts.sh" }, "inherits": [ - "../package.common.json" + "../package.common.json", + "./package.local.json" ], "jest": { "preset": "ts-jest/presets/default-esm", diff --git a/yarn-project/types/package.local.json b/yarn-project/types/package.local.json new file mode 100644 index 00000000000..40670e322ff --- /dev/null +++ b/yarn-project/types/package.local.json @@ -0,0 +1,7 @@ +{ + "scripts": { + "build": "yarn clean && yarn generate && tsc -b", + "generate": "yarn generate:noir-contracts", + "generate:noir-contracts": "./scripts/copy-contracts.sh" + } +} diff --git a/yarn-project/types/scripts/copy-contracts.sh b/yarn-project/types/scripts/copy-contracts.sh new file mode 100755 index 00000000000..d64da5b967a --- /dev/null +++ b/yarn-project/types/scripts/copy-contracts.sh @@ -0,0 +1,5 @@ +#! /bin/bash +set -euo pipefail +mkdir -p ./fixtures + +cp "../../noir-projects/noir-contracts/target/benchmarking_contract-Benchmarking.json" ./fixtures/Benchmarking.test.json diff --git a/yarn-project/types/src/abi/contract_artifact.test.ts b/yarn-project/types/src/abi/contract_artifact.test.ts new file mode 100644 index 00000000000..de830666e09 --- /dev/null +++ b/yarn-project/types/src/abi/contract_artifact.test.ts @@ -0,0 +1,12 @@ +import { getSampleContractArtifact } from '../test/fixtures.js'; +import { contractArtifactFromBuffer, contractArtifactToBuffer } from './contract_artifact.js'; + +describe('contract_artifact', () => { + it('serializes and deserializes an instance', () => { + const artifact = getSampleContractArtifact(); + delete artifact.aztecNrVersion; + const serialized = contractArtifactToBuffer(artifact); + const deserialized = contractArtifactFromBuffer(serialized); + expect(deserialized).toEqual(artifact); + }); +}); diff --git a/yarn-project/types/src/abi/contract_artifact.ts b/yarn-project/types/src/abi/contract_artifact.ts index 22ac7a7df8c..ac6208bb345 100644 --- a/yarn-project/types/src/abi/contract_artifact.ts +++ b/yarn-project/types/src/abi/contract_artifact.ts @@ -23,8 +23,21 @@ import { mockVerificationKey } from './mocked_keys.js'; * @returns A buffer. */ export function contractArtifactToBuffer(artifact: ContractArtifact): Buffer { - // TODO(@spalladino): More efficient serialization - return Buffer.from(JSON.stringify(artifact), 'utf8'); + return Buffer.from( + JSON.stringify(artifact, (key, value) => { + if ( + key === 'bytecode' && + value !== null && + typeof value === 'object' && + value.type === 'Buffer' && + Array.isArray(value.data) + ) { + return Buffer.from(value.data).toString('base64'); + } + return value; + }), + 'utf-8', + ); } /** @@ -33,8 +46,12 @@ export function contractArtifactToBuffer(artifact: ContractArtifact): Buffer { * @returns Deserialized artifact. */ export function contractArtifactFromBuffer(buffer: Buffer): ContractArtifact { - // TODO(@spalladino): More efficient serialization - return JSON.parse(buffer.toString('utf8')) as ContractArtifact; + return JSON.parse(buffer.toString('utf-8'), (key, value) => { + if (key === 'bytecode' && typeof value === 'string') { + return Buffer.from(value, 'base64'); + } + return value; + }); } /** diff --git a/yarn-project/types/src/test/fixtures.ts b/yarn-project/types/src/test/fixtures.ts new file mode 100644 index 00000000000..4395b58033d --- /dev/null +++ b/yarn-project/types/src/test/fixtures.ts @@ -0,0 +1,19 @@ +import { ContractArtifact } from '@aztec/foundation/abi'; + +import { readFileSync } from 'fs'; +import { dirname, resolve } from 'path'; +import { fileURLToPath } from 'url'; + +import { loadContractArtifact } from '../abi/contract_artifact.js'; +import { NoirCompiledContract } from '../noir/index.js'; + +// Copied from the build output for the contract `Benchmarking` in noir-contracts +export function getSampleContractArtifact(): ContractArtifact { + const path = getPathToFixture('Benchmarking.test.json'); + const content = JSON.parse(readFileSync(path).toString()) as NoirCompiledContract; + return loadContractArtifact(content); +} + +function getPathToFixture(name: string) { + return resolve(dirname(fileURLToPath(import.meta.url)), `../../fixtures/${name}`); +}