diff --git a/yarn-project/archiver/src/archiver/kv_archiver_store/block_store.ts b/yarn-project/archiver/src/archiver/kv_archiver_store/block_store.ts
index 91ae9d578c2..3d15de3fbbb 100644
--- a/yarn-project/archiver/src/archiver/kv_archiver_store/block_store.ts
+++ b/yarn-project/archiver/src/archiver/kv_archiver_store/block_store.ts
@@ -1,4 +1,4 @@
-import { Body, type InBlock, L2Block, type TxEffect, type TxHash, TxReceipt } from '@aztec/circuit-types';
+import { Body, type InBlock, L2Block, L2BlockHash, type TxEffect, type TxHash, TxReceipt } from '@aztec/circuit-types';
import { AppendOnlyTreeSnapshot, type AztecAddress, Header, INITIAL_L2_BLOCK_NUM } from '@aztec/circuits.js';
import { createDebugLogger } from '@aztec/foundation/log';
import { type AztecKVStore, type AztecMap, type AztecSingleton, type Range } from '@aztec/kv-store';
@@ -211,7 +211,7 @@ export class BlockStore {
TxReceipt.statusFromRevertCode(tx.revertCode),
'',
tx.transactionFee.toBigInt(),
- block.data.hash().toBuffer(),
+ L2BlockHash.fromField(block.data.hash()),
block.data.number,
);
}
diff --git a/yarn-project/archiver/src/archiver/memory_archiver_store/memory_archiver_store.ts b/yarn-project/archiver/src/archiver/memory_archiver_store/memory_archiver_store.ts
index 7f34e559ccc..df606d16fab 100644
--- a/yarn-project/archiver/src/archiver/memory_archiver_store/memory_archiver_store.ts
+++ b/yarn-project/archiver/src/archiver/memory_archiver_store/memory_archiver_store.ts
@@ -9,6 +9,7 @@ import {
type InBlock,
type InboxLeaf,
type L2Block,
+ L2BlockHash,
type L2BlockL2Logs,
type LogFilter,
LogId,
@@ -450,7 +451,7 @@ export class MemoryArchiverStore implements ArchiverDataStore {
TxReceipt.statusFromRevertCode(txEffect.revertCode),
'',
txEffect.transactionFee.toBigInt(),
- block.data.hash().toBuffer(),
+ L2BlockHash.fromField(block.data.hash()),
block.data.number,
),
);
diff --git a/yarn-project/archiver/src/index.ts b/yarn-project/archiver/src/index.ts
index ae7f86f8c20..24112863fc1 100644
--- a/yarn-project/archiver/src/index.ts
+++ b/yarn-project/archiver/src/index.ts
@@ -1,3 +1,4 @@
+import { jsonStringify } from '@aztec/foundation/json-rpc';
import { createDebugLogger } from '@aztec/foundation/log';
import { fileURLToPath } from '@aztec/foundation/url';
import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
@@ -25,7 +26,7 @@ async function main() {
const config = getArchiverConfigFromEnv();
const { l1RpcUrl: rpcUrl, l1Contracts } = config;
- log.info(`Starting archiver in main(): ${JSON.stringify(config)}`);
+ log.info(`Starting archiver in main(): ${jsonStringify(config)}`);
const publicClient = createPublicClient({
chain: localhost,
transport: http(rpcUrl),
diff --git a/yarn-project/archiver/src/test/mock_l2_block_source.ts b/yarn-project/archiver/src/test/mock_l2_block_source.ts
index 2ab843cb42a..cbd2e3363d3 100644
--- a/yarn-project/archiver/src/test/mock_l2_block_source.ts
+++ b/yarn-project/archiver/src/test/mock_l2_block_source.ts
@@ -1,4 +1,12 @@
-import { L2Block, type L2BlockSource, type L2Tips, type TxHash, TxReceipt, TxStatus } from '@aztec/circuit-types';
+import {
+ L2Block,
+ L2BlockHash,
+ type L2BlockSource,
+ type L2Tips,
+ type TxHash,
+ TxReceipt,
+ TxStatus,
+} from '@aztec/circuit-types';
import { EthAddress, type Header } from '@aztec/circuits.js';
import { DefaultL1ContractsConfig } from '@aztec/ethereum';
import { createDebugLogger } from '@aztec/foundation/log';
@@ -144,7 +152,7 @@ export class MockL2BlockSource implements L2BlockSource {
TxStatus.SUCCESS,
'',
txEffect.transactionFee.toBigInt(),
- block.hash().toBuffer(),
+ L2BlockHash.fromField(block.hash()),
block.number,
),
);
diff --git a/yarn-project/aztec-node/src/aztec-node/server.test.ts b/yarn-project/aztec-node/src/aztec-node/server.test.ts
index 29bbf20e274..666bd426440 100644
--- a/yarn-project/aztec-node/src/aztec-node/server.test.ts
+++ b/yarn-project/aztec-node/src/aztec-node/server.test.ts
@@ -143,12 +143,14 @@ describe('aztec node', () => {
maxBlockNumber: new MaxBlockNumber(true, new Fr(1)),
getSize: () => 1,
toBuffer: () => Fr.ZERO.toBuffer(),
+ toString: () => Fr.ZERO.toString(),
};
validMaxBlockNumberMetadata.data.rollupValidationRequests = {
maxBlockNumber: new MaxBlockNumber(true, new Fr(5)),
getSize: () => 1,
toBuffer: () => Fr.ZERO.toBuffer(),
+ toString: () => Fr.ZERO.toString(),
};
lastBlockNumber = 3;
diff --git a/yarn-project/aztec.js/src/rpc_clients/node/index.ts b/yarn-project/aztec.js/src/rpc_clients/node/index.ts
index 9cf3195f334..0db9d0edf35 100644
--- a/yarn-project/aztec.js/src/rpc_clients/node/index.ts
+++ b/yarn-project/aztec.js/src/rpc_clients/node/index.ts
@@ -1,8 +1,10 @@
import { type PXE } from '@aztec/circuit-types';
+import { jsonStringify } from '@aztec/foundation/json-rpc';
import { type DebugLogger } from '@aztec/foundation/log';
import { NoRetryError, makeBackoff, retry } from '@aztec/foundation/retry';
-import axios, { type AxiosError, type AxiosResponse } from 'axios';
+import { Axios, type AxiosError } from 'axios';
+import { inspect } from 'util';
import { createPXEClient } from '../pxe_client.js';
@@ -15,34 +17,19 @@ import { createPXEClient } from '../pxe_client.js';
* @returns The response data.
*/
async function axiosFetch(host: string, rpcMethod: string, body: any, useApiEndpoints: boolean) {
- let resp: AxiosResponse;
- if (useApiEndpoints) {
- resp = await axios
- .post(`${host}/${rpcMethod}`, body, {
- headers: { 'content-type': 'application/json' },
- })
- .catch((error: AxiosError) => {
- if (error.response) {
- return error.response;
- }
- throw error;
- });
- } else {
- resp = await axios
- .post(
- host,
- { ...body, method: rpcMethod },
- {
- headers: { 'content-type': 'application/json' },
- },
- )
- .catch((error: AxiosError) => {
- if (error.response) {
- return error.response;
- }
- throw error;
- });
- }
+ const request = new Axios({
+ headers: { 'content-type': 'application/json' },
+ transformRequest: [(data: any) => jsonStringify(data)],
+ transformResponse: [(data: any) => JSON.parse(data)],
+ });
+ const [url, content] = useApiEndpoints ? [`${host}/${rpcMethod}`, body] : [host, { ...body, method: rpcMethod }];
+ const resp = await request.post(url, content).catch((error: AxiosError) => {
+ if (error.response) {
+ return error.response;
+ }
+ const errorMessage = `Error fetching from host ${host} with method ${rpcMethod}: ${inspect(error)}`;
+ throw new Error(errorMessage);
+ });
const isOK = resp.status >= 200 && resp.status < 300;
if (isOK) {
diff --git a/yarn-project/aztec/src/examples/util.ts b/yarn-project/aztec/src/examples/util.ts
index 0d38e5beeef..2ba7c3e6e93 100644
--- a/yarn-project/aztec/src/examples/util.ts
+++ b/yarn-project/aztec/src/examples/util.ts
@@ -1,4 +1,5 @@
import { EthAddress } from '@aztec/aztec.js';
+import { jsonStringify } from '@aztec/foundation/json-rpc';
import type { Abi, Narrow } from 'abitype';
import { type Account, type Chain, type Hex, type HttpTransport, type PublicClient, type WalletClient } from 'viem';
@@ -28,7 +29,7 @@ export async function deployL1Contract(
const receipt = await publicClient.waitForTransactionReceipt({ hash });
const contractAddress = receipt.contractAddress;
if (!contractAddress) {
- throw new Error(`No contract address found in receipt: ${JSON.stringify(receipt)}`);
+ throw new Error(`No contract address found in receipt: ${jsonStringify(receipt)}`);
}
return EthAddress.fromString(receipt.contractAddress!);
diff --git a/yarn-project/bot/src/factory.ts b/yarn-project/bot/src/factory.ts
index b05e840fdb2..2a72653005a 100644
--- a/yarn-project/bot/src/factory.ts
+++ b/yarn-project/bot/src/factory.ts
@@ -70,7 +70,7 @@ export class BotFactory {
this.log.info(`Initializing account at ${account.getAddress().toString()}`);
const sentTx = account.deploy();
const txHash = await sentTx.getTxHash();
- this.log.info(`Sent tx with hash ${txHash.to0xString()}`);
+ this.log.info(`Sent tx with hash ${txHash.toString()}`);
if (this.config.flushSetupTransactions) {
this.log.verbose('Flushing transactions');
await this.node!.flushTxs();
@@ -117,7 +117,7 @@ export class BotFactory {
this.log.info(`Deploying token contract at ${address.toString()}`);
const sentTx = deploy.send(deployOpts);
const txHash = await sentTx.getTxHash();
- this.log.info(`Sent tx with hash ${txHash.to0xString()}`);
+ this.log.info(`Sent tx with hash ${txHash.toString()}`);
if (this.config.flushSetupTransactions) {
this.log.verbose('Flushing transactions');
await this.node!.flushTxs();
@@ -164,7 +164,7 @@ export class BotFactory {
}
const sentTx = new BatchCall(token.wallet, calls).send();
const txHash = await sentTx.getTxHash();
- this.log.info(`Sent tx with hash ${txHash.to0xString()}`);
+ this.log.info(`Sent tx with hash ${txHash.toString()}`);
if (this.config.flushSetupTransactions) {
this.log.verbose('Flushing transactions');
await this.node!.flushTxs();
diff --git a/yarn-project/circuit-types/src/auth_witness.ts b/yarn-project/circuit-types/src/auth_witness.ts
index f661817edbd..ea135a2d5dd 100644
--- a/yarn-project/circuit-types/src/auth_witness.ts
+++ b/yarn-project/circuit-types/src/auth_witness.ts
@@ -2,6 +2,7 @@ import { Vector } from '@aztec/circuits.js';
import { Fr } from '@aztec/foundation/fields';
import { hexSchemaFor } from '@aztec/foundation/schemas';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
/**
* An authentication witness. Used to authorize an action by a user.
@@ -37,12 +38,11 @@ export class AuthWitness {
}
toString() {
- return '0x' + this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
static fromString(str: string) {
- const hex = str.replace(/^0x/, '');
- return AuthWitness.fromBuffer(Buffer.from(hex, 'hex'));
+ return AuthWitness.fromBuffer(hexToBuffer(str));
}
static random() {
diff --git a/yarn-project/circuit-types/src/body.ts b/yarn-project/circuit-types/src/body.ts
index 48617fa2016..7c5d131a5c8 100644
--- a/yarn-project/circuit-types/src/body.ts
+++ b/yarn-project/circuit-types/src/body.ts
@@ -1,3 +1,4 @@
+import { type ZodFor } from '@aztec/foundation/schemas';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
import { computeUnbalancedMerkleRoot } from '@aztec/foundation/trees';
@@ -21,7 +22,7 @@ export class Body {
});
}
- static get schema() {
+ static get schema(): ZodFor
{
return z
.object({
txEffects: z.array(TxEffect.schema),
@@ -29,10 +30,6 @@ export class Body {
.transform(({ txEffects }) => new Body(txEffects));
}
- toJSON() {
- return { txEffects: this.txEffects };
- }
-
/**
* Serializes a block body
* @returns A serialized L2 block body.
diff --git a/yarn-project/circuit-types/src/interfaces/nullifier_tree.ts b/yarn-project/circuit-types/src/interfaces/nullifier_tree.ts
index bfc6097ab09..ec46c4d99e9 100644
--- a/yarn-project/circuit-types/src/interfaces/nullifier_tree.ts
+++ b/yarn-project/circuit-types/src/interfaces/nullifier_tree.ts
@@ -54,20 +54,4 @@ export class NullifierMembershipWitness {
public toFields(): Fr[] {
return [new Fr(this.index), ...this.leafPreimage.toFields(), ...this.siblingPath.toFields()];
}
-
- public toJSON() {
- return {
- index: '0x' + this.index.toString(16),
- leafPreimage: this.leafPreimage.toJSON(),
- siblingPath: this.siblingPath.toString(),
- };
- }
-
- static fromJSON(json: any): NullifierMembershipWitness {
- return new NullifierMembershipWitness(
- BigInt(json.index),
- NullifierLeafPreimage.fromJSON(json.leafPreimage),
- SiblingPath.fromString(json.siblingPath),
- );
- }
}
diff --git a/yarn-project/circuit-types/src/l2_block.ts b/yarn-project/circuit-types/src/l2_block.ts
index bf5f8bffe33..169ff874fd6 100644
--- a/yarn-project/circuit-types/src/l2_block.ts
+++ b/yarn-project/circuit-types/src/l2_block.ts
@@ -1,7 +1,8 @@
-import { AppendOnlyTreeSnapshot, Header, STRING_ENCODING } from '@aztec/circuits.js';
+import { AppendOnlyTreeSnapshot, Header } from '@aztec/circuits.js';
import { sha256, sha256ToField } from '@aztec/foundation/crypto';
import { Fr } from '@aztec/foundation/fields';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { z } from 'zod';
@@ -31,14 +32,6 @@ export class L2Block {
.transform(({ archive, header, body }) => new L2Block(archive, header, body));
}
- toJSON() {
- return {
- archive: this.archive,
- header: this.header,
- body: this.body,
- };
- }
-
/**
* Deserializes a block from a buffer
* @returns A deserialized L2 block.
@@ -66,7 +59,7 @@ export class L2Block {
* @returns Deserialized L2 block.
*/
static fromString(str: string): L2Block {
- return L2Block.fromBuffer(Buffer.from(str, STRING_ENCODING));
+ return L2Block.fromBuffer(hexToBuffer(str));
}
/**
@@ -74,7 +67,7 @@ export class L2Block {
* @returns A serialized L2 block as a string.
*/
toString(): string {
- return this.toBuffer().toString(STRING_ENCODING);
+ return bufferToHex(this.toBuffer());
}
/**
diff --git a/yarn-project/circuit-types/src/l2_block_downloader/l2_block_stream.test.ts b/yarn-project/circuit-types/src/l2_block_downloader/l2_block_stream.test.ts
index 756c598eb1e..bb8eaafc83a 100644
--- a/yarn-project/circuit-types/src/l2_block_downloader/l2_block_stream.test.ts
+++ b/yarn-project/circuit-types/src/l2_block_downloader/l2_block_stream.test.ts
@@ -42,7 +42,7 @@ describe('L2BlockStream', () => {
const makeBlock = (number: number) => ({ number } as L2Block);
- const makeHeader = (number: number) => mock({ hash: () => new Fr(number) });
+ const makeHeader = (number: number) => mock({ hash: () => new Fr(number) } as Header);
const setRemoteTips = (latest_: number, proven?: number, finalized?: number) => {
proven = proven ?? 0;
diff --git a/yarn-project/circuit-types/src/logs/encrypted_l2_log.ts b/yarn-project/circuit-types/src/logs/encrypted_l2_log.ts
index f59b98fa6a6..da67376b042 100644
--- a/yarn-project/circuit-types/src/logs/encrypted_l2_log.ts
+++ b/yarn-project/circuit-types/src/logs/encrypted_l2_log.ts
@@ -25,23 +25,10 @@ export class EncryptedL2Log {
static get schema() {
return z
- .object({ data: schemas.BufferHex, maskedContractAddress: schemas.Fr })
+ .object({ data: schemas.Buffer, maskedContractAddress: schemas.Fr })
.transform(({ data, maskedContractAddress }) => new EncryptedL2Log(data, maskedContractAddress));
}
- /** Returns a JSON-friendly representation of the log. */
- public toJSON(): object {
- return {
- data: this.data.toString('hex'),
- maskedContractAddress: this.maskedContractAddress.toString(),
- };
- }
-
- /** Converts a plain JSON object into an instance. */
- public static fromJSON(obj: any) {
- return new EncryptedL2Log(Buffer.from(obj.data, 'hex'), Fr.fromString(obj.maskedContractAddress));
- }
-
/**
* Deserializes log from a buffer.
* @param buffer - The buffer containing the log.
diff --git a/yarn-project/circuit-types/src/logs/encrypted_l2_note_log.ts b/yarn-project/circuit-types/src/logs/encrypted_l2_note_log.ts
index 23f5a2a99b1..62d4d7ff62d 100644
--- a/yarn-project/circuit-types/src/logs/encrypted_l2_note_log.ts
+++ b/yarn-project/circuit-types/src/logs/encrypted_l2_note_log.ts
@@ -25,20 +25,8 @@ export class EncryptedL2NoteLog {
return this.data;
}
- /** Returns a JSON-friendly representation of the log. */
- public toJSON(): object {
- return { data: this.data.toString('hex') };
- }
-
static get schema() {
- return z
- .object({ data: schemas.HexString })
- .transform(({ data }) => new EncryptedL2NoteLog(Buffer.from(data, 'hex')));
- }
-
- /** Converts a plain JSON object into an instance. */
- public static fromJSON(obj: any) {
- return new EncryptedL2NoteLog(Buffer.from(obj.data, 'hex'));
+ return z.object({ data: schemas.Buffer }).transform(({ data }) => new EncryptedL2NoteLog(data));
}
/**
diff --git a/yarn-project/circuit-types/src/logs/event_metadata.ts b/yarn-project/circuit-types/src/logs/event_metadata.ts
index b63d8b8bba5..e5b4a89f221 100644
--- a/yarn-project/circuit-types/src/logs/event_metadata.ts
+++ b/yarn-project/circuit-types/src/logs/event_metadata.ts
@@ -1,4 +1,4 @@
-import { type AbiType, AbiTypeSchema, EventSelector, decodeFromAbi } from '@aztec/foundation/abi';
+import { type AbiType, AbiTypeSchema, type EventSelector, decodeFromAbi } from '@aztec/foundation/abi';
import { Fr } from '@aztec/foundation/fields';
import { schemas } from '@aztec/foundation/schemas';
@@ -49,37 +49,13 @@ export class EventMetadata {
};
}
- /**
- * Serializes the metadata to a JSON-friendly format
- */
- public toJSON() {
- return {
- type: 'event_metadata', // TODO(palla/schemas): Remove this type property
- eventSelector: this.eventSelector,
- abiType: this.abiType,
- fieldNames: this.fieldNames,
- };
- }
-
static get schema() {
return z
.object({
eventSelector: schemas.EventSelector,
abiType: AbiTypeSchema,
fieldNames: z.array(z.string()),
- type: z.literal('event_metadata').optional(),
})
.transform(obj => new EventMetadata(obj));
}
-
- /**
- * Creates an EventMetadata instance from a JSON representation
- */
- public static fromJSON(json: any): EventMetadata {
- return new EventMetadata({
- eventSelector: EventSelector.fromString(json.eventSelector),
- abiType: json.abiType,
- fieldNames: json.fieldNames,
- });
- }
}
diff --git a/yarn-project/circuit-types/src/logs/extended_unencrypted_l2_log.ts b/yarn-project/circuit-types/src/logs/extended_unencrypted_l2_log.ts
index b571879aacd..9bdab9deeb4 100644
--- a/yarn-project/circuit-types/src/logs/extended_unencrypted_l2_log.ts
+++ b/yarn-project/circuit-types/src/logs/extended_unencrypted_l2_log.ts
@@ -1,4 +1,5 @@
import { BufferReader } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { type FieldsOf } from '@aztec/foundation/types';
import isEqual from 'lodash.isequal';
@@ -22,10 +23,6 @@ export class ExtendedUnencryptedL2Log {
return new ExtendedUnencryptedL2Log(LogId.random(), UnencryptedL2Log.random());
}
- toJSON() {
- return { id: this.id, log: this.log };
- }
-
static get schema() {
return z
.object({
@@ -52,7 +49,7 @@ export class ExtendedUnencryptedL2Log {
* @returns A string containing the serialized log.
*/
public toString(): string {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
/**
@@ -92,7 +89,6 @@ export class ExtendedUnencryptedL2Log {
* @returns An `ExtendedUnencryptedL2Log` object.
*/
public static fromString(data: string): ExtendedUnencryptedL2Log {
- const buffer = Buffer.from(data, 'hex');
- return ExtendedUnencryptedL2Log.fromBuffer(buffer);
+ return ExtendedUnencryptedL2Log.fromBuffer(hexToBuffer(data));
}
}
diff --git a/yarn-project/circuit-types/src/logs/function_l2_logs.test.ts b/yarn-project/circuit-types/src/logs/function_l2_logs.test.ts
index 5effe039a0c..d0f49d57c7c 100644
--- a/yarn-project/circuit-types/src/logs/function_l2_logs.test.ts
+++ b/yarn-project/circuit-types/src/logs/function_l2_logs.test.ts
@@ -1,3 +1,5 @@
+import { jsonStringify } from '@aztec/foundation/json-rpc';
+
import { EncryptedFunctionL2Logs, EncryptedNoteFunctionL2Logs, UnencryptedFunctionL2Logs } from './function_l2_logs.js';
function shouldBehaveLikeFunctionL2Logs(
@@ -19,8 +21,8 @@ function shouldBehaveLikeFunctionL2Logs(
it('can encode L2Logs to JSON and back', () => {
const l2Logs = FunctionL2Logs.random(3);
- const buffer = JSON.stringify(l2Logs.toJSON());
- const recovered = FunctionL2Logs.fromJSON(JSON.parse(buffer));
+ const buffer = jsonStringify(l2Logs);
+ const recovered = FunctionL2Logs.schema.parse(JSON.parse(buffer));
expect(recovered).toEqual(l2Logs);
});
diff --git a/yarn-project/circuit-types/src/logs/function_l2_logs.ts b/yarn-project/circuit-types/src/logs/function_l2_logs.ts
index e3127e63cd6..2171fb2c17e 100644
--- a/yarn-project/circuit-types/src/logs/function_l2_logs.ts
+++ b/yarn-project/circuit-types/src/logs/function_l2_logs.ts
@@ -62,14 +62,6 @@ export abstract class FunctionL2Logs l.hash()));
return sha256Trunc(preimage);
}
-
- /**
- * Convert a FunctionL2Logs class object to a plain JSON object.
- * @returns A plain object with FunctionL2Logs properties.
- */
- public toJSON() {
- return { logs: this.logs };
- }
}
export class EncryptedNoteFunctionL2Logs extends FunctionL2Logs {
@@ -118,16 +110,6 @@ export class EncryptedNoteFunctionL2Logs extends FunctionL2Logs {
@@ -176,16 +158,6 @@ export class EncryptedFunctionL2Logs extends FunctionL2Logs {
}
return new EncryptedFunctionL2Logs(logs);
}
-
- /**
- * Convert a plain JSON object to a FunctionL2Logs class object.
- * @param obj - A plain FunctionL2Logs JSON object.
- * @returns A FunctionL2Logs class object.
- */
- public static fromJSON(obj: any) {
- const logs = obj.logs.map(EncryptedL2Log.fromJSON);
- return new EncryptedFunctionL2Logs(logs);
- }
}
export class UnencryptedFunctionL2Logs extends FunctionL2Logs {
@@ -234,14 +206,4 @@ export class UnencryptedFunctionL2Logs extends FunctionL2Logs
}
return new UnencryptedFunctionL2Logs(logs);
}
-
- /**
- * Convert a plain JSON object to a FunctionL2Logs class object.
- * @param obj - A plain FunctionL2Logs JSON object.
- * @returns A FunctionL2Logs class object.
- */
- public static fromJSON(obj: any) {
- const logs = obj.logs.map(UnencryptedL2Log.fromJSON);
- return new UnencryptedFunctionL2Logs(logs);
- }
}
diff --git a/yarn-project/circuit-types/src/logs/get_logs_response.ts b/yarn-project/circuit-types/src/logs/get_logs_response.ts
index 6f1d156be0b..62b2ff6d833 100644
--- a/yarn-project/circuit-types/src/logs/get_logs_response.ts
+++ b/yarn-project/circuit-types/src/logs/get_logs_response.ts
@@ -52,7 +52,7 @@ export class TxScopedL2Log {
dataStartIndexForTx: z.number(),
blockNumber: z.number(),
isFromPublic: z.boolean(),
- logData: schemas.BufferB64,
+ logData: schemas.Buffer,
})
.transform(
({ txHash, dataStartIndexForTx, blockNumber, isFromPublic, logData }) =>
diff --git a/yarn-project/circuit-types/src/logs/l1_payload/payload.test.ts b/yarn-project/circuit-types/src/logs/l1_payload/payload.test.ts
index a4fa27d833a..6dc3a358683 100644
--- a/yarn-project/circuit-types/src/logs/l1_payload/payload.test.ts
+++ b/yarn-project/circuit-types/src/logs/l1_payload/payload.test.ts
@@ -1,13 +1,23 @@
import { Fr } from '@aztec/foundation/fields';
+import { jsonParseWithSchema, jsonStringify } from '@aztec/foundation/json-rpc';
+
+import times from 'lodash.times';
import { Event, Note } from './payload.js';
describe('note', () => {
+ let note: Note;
+
+ beforeEach(() => {
+ note = new Note(times(5, Fr.random));
+ });
+
it('convert to and from buffer', () => {
- const fields = Array.from({ length: 5 }).map(() => Fr.random());
- const note = new Note(fields);
- const buf = note.toBuffer();
- expect(Note.fromBuffer(buf)).toEqual(note);
+ expect(Note.fromBuffer(note.toBuffer())).toEqual(note);
+ });
+
+ it('converts to and from json', () => {
+ expect(jsonParseWithSchema(jsonStringify(note), Note.schema)).toEqual(note);
});
});
diff --git a/yarn-project/circuit-types/src/logs/l1_payload/payload.ts b/yarn-project/circuit-types/src/logs/l1_payload/payload.ts
index cc460a2a3cd..4bcad7408fc 100644
--- a/yarn-project/circuit-types/src/logs/l1_payload/payload.ts
+++ b/yarn-project/circuit-types/src/logs/l1_payload/payload.ts
@@ -1,8 +1,9 @@
import { Vector } from '@aztec/circuits.js';
import { randomInt } from '@aztec/foundation/crypto';
import { Fr } from '@aztec/foundation/fields';
-import { hexSchemaFor } from '@aztec/foundation/schemas';
+import { schemas } from '@aztec/foundation/schemas';
import { BufferReader } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
/**
* The Note class represents a Note emitted from a Noir contract as a vector of Fr (finite field) elements.
@@ -11,11 +12,11 @@ import { BufferReader } from '@aztec/foundation/serialize';
*/
export class Payload extends Vector {
toJSON() {
- return this.toString();
+ return this.toBuffer();
}
static get schema() {
- return hexSchemaFor(Payload);
+ return schemas.Buffer.transform(Payload.fromBuffer);
}
/**
@@ -49,7 +50,7 @@ export class Payload extends Vector {
* @returns A hex string with the vector length as first element.
*/
override toString() {
- return '0x' + this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
/**
@@ -58,8 +59,7 @@ export class Payload extends Vector {
* @returns A Note instance.
*/
static fromString(str: string) {
- const hex = str.replace(/^0x/, '');
- return Payload.fromBuffer(Buffer.from(hex, 'hex'));
+ return Payload.fromBuffer(hexToBuffer(str));
}
get length() {
@@ -71,6 +71,24 @@ export class Payload extends Vector {
}
}
-export class Event extends Payload {}
+export class Event extends Payload {
+ static override get schema() {
+ return schemas.Buffer.transform(Event.fromBuffer);
+ }
+
+ static override fromBuffer(buffer: Buffer | BufferReader) {
+ const reader = BufferReader.asReader(buffer);
+ return new Event(reader.readVector(Fr));
+ }
+}
-export class Note extends Payload {}
+export class Note extends Payload {
+ static override get schema() {
+ return schemas.Buffer.transform(Note.fromBuffer);
+ }
+
+ static override fromBuffer(buffer: Buffer | BufferReader) {
+ const reader = BufferReader.asReader(buffer);
+ return new Note(reader.readVector(Fr));
+ }
+}
diff --git a/yarn-project/circuit-types/src/logs/l2_block_l2_logs.test.ts b/yarn-project/circuit-types/src/logs/l2_block_l2_logs.test.ts
index 41ea8c0eee8..e16b963525b 100644
--- a/yarn-project/circuit-types/src/logs/l2_block_l2_logs.test.ts
+++ b/yarn-project/circuit-types/src/logs/l2_block_l2_logs.test.ts
@@ -45,17 +45,6 @@ function shouldBehaveLikeL2BlockL2Logs(
}
});
- it('serializes to and from JSON via fromJSON', () => {
- const l2Logs =
- L2BlockL2Logs.name == 'ContractClass2BlockL2Logs'
- ? L2BlockL2Logs.random(3, 1, 1)
- : L2BlockL2Logs.random(3, 4, 2);
- const json = jsonStringify(l2Logs);
- const recovered = L2BlockL2Logs.fromJSON(JSON.parse(json));
- expect(recovered).toEqual(l2Logs);
- expect(recovered).toBeInstanceOf(L2BlockL2Logs);
- });
-
it('serializes to and from JSON via schema', () => {
const l2Logs =
L2BlockL2Logs.name == 'ContractClass2BlockL2Logs'
diff --git a/yarn-project/circuit-types/src/logs/l2_block_l2_logs.ts b/yarn-project/circuit-types/src/logs/l2_block_l2_logs.ts
index 2698fc2fc12..82bf2d4a899 100644
--- a/yarn-project/circuit-types/src/logs/l2_block_l2_logs.ts
+++ b/yarn-project/circuit-types/src/logs/l2_block_l2_logs.ts
@@ -1,5 +1,6 @@
import { type ZodFor } from '@aztec/foundation/schemas';
import { BufferReader, prefixBufferWithLength } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import isEqual from 'lodash.isequal';
import { z } from 'zod';
@@ -70,7 +71,7 @@ export abstract class L2BlockL2Logs EncryptedNoteTxL2Logs.fromJSON(log));
- return new EncryptedNoteL2BlockL2Logs(txLogs);
- }
-
/**
* Deserializes logs from a buffer.
* @param buffer - The buffer containing the serialized logs.
@@ -144,8 +135,7 @@ export class EncryptedNoteL2BlockL2Logs extends L2BlockL2Logs {
return 'Encrypted';
}
- /**
- * Convert a plain JSON object to a L2BlockL2Logs class object.
- * @param obj - A plain L2BlockL2Logs JSON object.
- * @returns A L2BlockL2Logs class object.
- */
- public static fromJSON(obj: any) {
- const txLogs = obj.txLogs.map((log: any) => EncryptedTxL2Logs.fromJSON(log));
- return new EncryptedL2BlockL2Logs(txLogs);
- }
-
/**
* Deserializes logs from a buffer.
* @param buffer - The buffer containing the serialized logs.
@@ -225,8 +205,7 @@ export class EncryptedL2BlockL2Logs extends L2BlockL2Logs {
* @returns A new `L2BlockL2Logs` object.
*/
public static fromString(data: string): EncryptedL2BlockL2Logs {
- const buffer = Buffer.from(data, 'hex');
- return EncryptedL2BlockL2Logs.fromBuffer(buffer);
+ return EncryptedL2BlockL2Logs.fromBuffer(hexToBuffer(data));
}
/**
@@ -275,16 +254,6 @@ export class UnencryptedL2BlockL2Logs extends L2BlockL2Logs {
return 'Unencrypted';
}
- /**
- * Convert a plain JSON object to a L2BlockL2Logs class object.
- * @param obj - A plain L2BlockL2Logs JSON object.
- * @returns A L2BlockL2Logs class object.
- */
- public static fromJSON(obj: any) {
- const txLogs = obj.txLogs.map((log: any) => UnencryptedTxL2Logs.fromJSON(log));
- return new UnencryptedL2BlockL2Logs(txLogs);
- }
-
/**
* Deserializes logs from a buffer.
* @param buffer - The buffer containing the serialized logs.
@@ -306,8 +275,7 @@ export class UnencryptedL2BlockL2Logs extends L2BlockL2Logs {
* @returns A new `L2BlockL2Logs` object.
*/
public static fromString(data: string): UnencryptedL2BlockL2Logs {
- const buffer = Buffer.from(data, 'hex');
- return UnencryptedL2BlockL2Logs.fromBuffer(buffer);
+ return UnencryptedL2BlockL2Logs.fromBuffer(hexToBuffer(data));
}
/**
@@ -358,16 +326,6 @@ export class ContractClass2BlockL2Logs extends L2BlockL2Logs {
return 'ContractClass';
}
- /**
- * Convert a plain JSON object to a L2BlockL2Logs class object.
- * @param obj - A plain L2BlockL2Logs JSON object.
- * @returns A L2BlockL2Logs class object.
- */
- public static fromJSON(obj: any) {
- const txLogs = obj.txLogs.map((log: any) => ContractClassTxL2Logs.fromJSON(log));
- return new ContractClass2BlockL2Logs(txLogs);
- }
-
/**
* Deserializes logs from a buffer.
* @param buffer - The buffer containing the serialized logs.
@@ -389,8 +347,7 @@ export class ContractClass2BlockL2Logs extends L2BlockL2Logs {
* @returns A new `L2BlockL2Logs` object.
*/
public static fromString(data: string): ContractClass2BlockL2Logs {
- const buffer = Buffer.from(data, 'hex');
- return ContractClass2BlockL2Logs.fromBuffer(buffer);
+ return ContractClass2BlockL2Logs.fromBuffer(hexToBuffer(data));
}
/**
diff --git a/yarn-project/circuit-types/src/logs/log_id.ts b/yarn-project/circuit-types/src/logs/log_id.ts
index 731763b1f07..fe718fb3821 100644
--- a/yarn-project/circuit-types/src/logs/log_id.ts
+++ b/yarn-project/circuit-types/src/logs/log_id.ts
@@ -50,14 +50,6 @@ export class LogId {
.transform(({ blockNumber, txIndex, logIndex }) => new LogId(blockNumber, txIndex, logIndex));
}
- toJSON() {
- return {
- blockNumber: this.blockNumber,
- txIndex: this.txIndex,
- logIndex: this.logIndex,
- };
- }
-
/**
* Serializes log id to a buffer.
* @returns A buffer containing the serialized log id.
diff --git a/yarn-project/circuit-types/src/logs/tx_l2_logs.test.ts b/yarn-project/circuit-types/src/logs/tx_l2_logs.test.ts
index 5fd7831ebe5..6bec9823692 100644
--- a/yarn-project/circuit-types/src/logs/tx_l2_logs.test.ts
+++ b/yarn-project/circuit-types/src/logs/tx_l2_logs.test.ts
@@ -22,8 +22,8 @@ function shouldBehaveLikeTxL2Logs(
it('can encode TxL2Logs to JSON and back', () => {
const l2Logs = TxL2Logs.name == 'ContractClassTxL2Logs' ? TxL2Logs.random(1, 1) : TxL2Logs.random(4, 2);
- const buffer = jsonStringify(l2Logs.toJSON());
- const recovered = TxL2Logs.fromJSON(JSON.parse(buffer));
+ const buffer = jsonStringify(l2Logs);
+ const recovered = TxL2Logs.schema.parse(JSON.parse(buffer));
expect(recovered).toEqual(l2Logs);
});
diff --git a/yarn-project/circuit-types/src/logs/tx_l2_logs.ts b/yarn-project/circuit-types/src/logs/tx_l2_logs.ts
index afa1f715752..b27b2346f02 100644
--- a/yarn-project/circuit-types/src/logs/tx_l2_logs.ts
+++ b/yarn-project/circuit-types/src/logs/tx_l2_logs.ts
@@ -76,16 +76,6 @@ export abstract class TxL2Logs log.toJSON()),
- };
- }
-
/**
* Unrolls logs from this tx.
* @returns Unrolled logs.
@@ -209,16 +199,6 @@ export class UnencryptedTxL2Logs extends TxL2Logs {
return new UnencryptedTxL2Logs(functionLogs);
}
- /**
- * Convert a plain JSON object to a TxL2Logs class object.
- * @param obj - A plain TxL2Logs JSON object.
- * @returns A TxL2Logs class object.
- */
- public static fromJSON(obj: any) {
- const functionLogs = obj.functionLogs.map((log: any) => UnencryptedFunctionL2Logs.fromJSON(log));
- return new UnencryptedTxL2Logs(functionLogs);
- }
-
/**
* Computes unencrypted logs hash as is done in the kernel and decoder contract.
* @param logs - Logs to be hashed.
@@ -303,16 +283,6 @@ export class EncryptedNoteTxL2Logs extends TxL2Logs {
return new EncryptedNoteTxL2Logs(functionLogs);
}
- /**
- * Convert a plain JSON object to a TxL2Logs class object.
- * @param obj - A plain TxL2Logs JSON object.
- * @returns A TxL2Logs class object.
- */
- public static fromJSON(obj: any) {
- const functionLogs = obj.functionLogs.map((log: any) => EncryptedNoteFunctionL2Logs.fromJSON(log));
- return new EncryptedNoteTxL2Logs(functionLogs);
- }
-
/**
* Computes encrypted logs hash as is done in the kernel and decoder contract.
* @param logs - Logs to be hashed.
@@ -396,16 +366,6 @@ export class EncryptedTxL2Logs extends TxL2Logs {
return new EncryptedTxL2Logs(functionLogs);
}
- /**
- * Convert a plain JSON object to a TxL2Logs class object.
- * @param obj - A plain TxL2Logs JSON object.
- * @returns A TxL2Logs class object.
- */
- public static fromJSON(obj: any) {
- const functionLogs = obj.functionLogs.map((log: any) => EncryptedFunctionL2Logs.fromJSON(log));
- return new EncryptedTxL2Logs(functionLogs);
- }
-
/**
* Computes encrypted logs hash as is done in the kernel and decoder contract.
* @param logs - Logs to be hashed.
@@ -490,16 +450,6 @@ export class ContractClassTxL2Logs extends TxL2Logs {
return new ContractClassTxL2Logs(functionLogs);
}
- /**
- * Convert a plain JSON object to a TxL2Logs class object.
- * @param obj - A plain TxL2Logs JSON object.
- * @returns A TxL2Logs class object.
- */
- public static fromJSON(obj: any) {
- const functionLogs = obj.functionLogs.map((log: any) => UnencryptedFunctionL2Logs.fromJSON(log));
- return new ContractClassTxL2Logs(functionLogs);
- }
-
/**
* @param logs - Logs to be hashed.
* @returns The hash of the logs.
diff --git a/yarn-project/circuit-types/src/logs/unencrypted_l2_log.test.ts b/yarn-project/circuit-types/src/logs/unencrypted_l2_log.test.ts
index 60f89766d9d..7917be9f8a6 100644
--- a/yarn-project/circuit-types/src/logs/unencrypted_l2_log.test.ts
+++ b/yarn-project/circuit-types/src/logs/unencrypted_l2_log.test.ts
@@ -1,3 +1,5 @@
+import { jsonStringify } from '@aztec/foundation/json-rpc';
+
import { UnencryptedL2Log } from './unencrypted_l2_log.js';
describe('UnencryptedL2Log', () => {
@@ -9,4 +11,13 @@ describe('UnencryptedL2Log', () => {
expect(recovered).toEqual(l2Logs);
});
+
+ it('can encode to JSON and back', () => {
+ const l2Logs = UnencryptedL2Log.random();
+
+ const buffer = jsonStringify(l2Logs);
+ const recovered = UnencryptedL2Log.schema.parse(JSON.parse(buffer));
+
+ expect(recovered).toEqual(l2Logs);
+ });
});
diff --git a/yarn-project/circuit-types/src/logs/unencrypted_l2_log.ts b/yarn-project/circuit-types/src/logs/unencrypted_l2_log.ts
index b43778409a9..942dad32db2 100644
--- a/yarn-project/circuit-types/src/logs/unencrypted_l2_log.ts
+++ b/yarn-project/circuit-types/src/logs/unencrypted_l2_log.ts
@@ -48,23 +48,10 @@ export class UnencryptedL2Log {
static get schema() {
return z
- .object({ contractAddress: schemas.AztecAddress, data: schemas.BufferHex })
+ .object({ contractAddress: schemas.AztecAddress, data: schemas.Buffer })
.transform(({ contractAddress, data }) => new UnencryptedL2Log(contractAddress, data));
}
- /** Returns a JSON-friendly representation of the log. */
- public toJSON(): object {
- return {
- contractAddress: this.contractAddress.toString(),
- data: this.data.toString('hex'),
- };
- }
-
- /** Converts a plain JSON object into an instance. */
- public static fromJSON(obj: any) {
- return new UnencryptedL2Log(AztecAddress.fromString(obj.contractAddress), Buffer.from(obj.data, 'hex'));
- }
-
/**
* Deserializes log from a buffer.
* @param buffer - The buffer or buffer reader containing the log.
diff --git a/yarn-project/circuit-types/src/messaging/l1_to_l2_message.ts b/yarn-project/circuit-types/src/messaging/l1_to_l2_message.ts
index e68a73a83e8..3dc438940e2 100644
--- a/yarn-project/circuit-types/src/messaging/l1_to_l2_message.ts
+++ b/yarn-project/circuit-types/src/messaging/l1_to_l2_message.ts
@@ -4,6 +4,7 @@ import { type AztecAddress } from '@aztec/foundation/aztec-address';
import { sha256ToField } from '@aztec/foundation/crypto';
import { Fr } from '@aztec/foundation/fields';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex } from '@aztec/foundation/string';
import { type AztecNode } from '../interfaces/aztec-node.js';
import { MerkleTreeId } from '../merkle_tree_id.js';
@@ -55,7 +56,7 @@ export class L1ToL2Message {
}
toString(): string {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
static fromString(data: string): L1ToL2Message {
diff --git a/yarn-project/circuit-types/src/notes/extended_note.test.ts b/yarn-project/circuit-types/src/notes/extended_note.test.ts
index 25a2280b527..a5035cc5406 100644
--- a/yarn-project/circuit-types/src/notes/extended_note.test.ts
+++ b/yarn-project/circuit-types/src/notes/extended_note.test.ts
@@ -1,18 +1,40 @@
+import { jsonStringify } from '@aztec/foundation/json-rpc';
+
import { randomExtendedNote, randomUniqueNote } from '../mocks.js';
import { ExtendedNote, UniqueNote } from './extended_note.js';
-describe('Extended Note', () => {
+describe('ExtendedNote', () => {
+ let note: ExtendedNote;
+
+ beforeEach(() => {
+ note = randomExtendedNote();
+ });
+
it('convert to and from buffer', () => {
- const extendedNote = randomExtendedNote();
- const buf = extendedNote.toBuffer();
- expect(ExtendedNote.fromBuffer(buf)).toEqual(extendedNote);
+ const buf = note.toBuffer();
+ expect(ExtendedNote.fromBuffer(buf)).toEqual(note);
+ });
+
+ it('convert to and from JSON', () => {
+ const json = jsonStringify(note);
+ expect(ExtendedNote.schema.parse(JSON.parse(json))).toEqual(note);
});
});
-describe('Unique Note', () => {
+describe('UniqueNote', () => {
+ let note: UniqueNote;
+
+ beforeEach(() => {
+ note = randomUniqueNote();
+ });
+
it('convert to and from buffer', () => {
- const uniqueNote = randomUniqueNote();
- const buf = uniqueNote.toBuffer();
- expect(UniqueNote.fromBuffer(buf)).toEqual(uniqueNote);
+ const buf = note.toBuffer();
+ expect(UniqueNote.fromBuffer(buf)).toEqual(note);
+ });
+
+ it('convert to and from JSON', () => {
+ const json = jsonStringify(note);
+ expect(UniqueNote.schema.parse(JSON.parse(json))).toEqual(note);
});
});
diff --git a/yarn-project/circuit-types/src/notes/extended_note.ts b/yarn-project/circuit-types/src/notes/extended_note.ts
index a3c3506cdbb..cac982b01b8 100644
--- a/yarn-project/circuit-types/src/notes/extended_note.ts
+++ b/yarn-project/circuit-types/src/notes/extended_note.ts
@@ -1,7 +1,10 @@
import { AztecAddress, Fr } from '@aztec/circuits.js';
import { NoteSelector } from '@aztec/foundation/abi';
-import { hexSchemaFor } from '@aztec/foundation/schemas';
+import { schemas } from '@aztec/foundation/schemas';
import { BufferReader } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
+
+import { z } from 'zod';
import { Note } from '../logs/l1_payload/payload.js';
import { TxHash } from '../tx/tx_hash.js';
@@ -49,21 +52,27 @@ export class ExtendedNote {
return new this(note, owner, contractAddress, storageSlot, noteTypeId, txHash);
}
- toJSON() {
- return this.toString();
- }
-
static get schema() {
- return hexSchemaFor(ExtendedNote);
+ return z
+ .object({
+ note: Note.schema,
+ owner: schemas.AztecAddress,
+ contractAddress: schemas.AztecAddress,
+ storageSlot: schemas.Fr,
+ noteTypeId: schemas.NoteSelector,
+ txHash: TxHash.schema,
+ })
+ .transform(({ note, owner, contractAddress, storageSlot, noteTypeId, txHash }) => {
+ return new ExtendedNote(note, owner, contractAddress, storageSlot, noteTypeId, txHash);
+ });
}
toString() {
- return '0x' + this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
static fromString(str: string) {
- const hex = str.replace(/^0x/, '');
- return ExtendedNote.fromBuffer(Buffer.from(hex, 'hex'));
+ return ExtendedNote.fromBuffer(hexToBuffer(str));
}
static random() {
@@ -99,7 +108,19 @@ export class UniqueNote extends ExtendedNote {
}
static override get schema() {
- return hexSchemaFor(UniqueNote);
+ return z
+ .object({
+ note: Note.schema,
+ owner: schemas.AztecAddress,
+ contractAddress: schemas.AztecAddress,
+ storageSlot: schemas.Fr,
+ noteTypeId: schemas.NoteSelector,
+ txHash: TxHash.schema,
+ nonce: schemas.Fr,
+ })
+ .transform(({ note, owner, contractAddress, storageSlot, noteTypeId, txHash, nonce }) => {
+ return new UniqueNote(note, owner, contractAddress, storageSlot, noteTypeId, txHash, nonce);
+ });
}
override toBuffer(): Buffer {
@@ -141,7 +162,6 @@ export class UniqueNote extends ExtendedNote {
}
static override fromString(str: string) {
- const hex = str.replace(/^0x/, '');
- return UniqueNote.fromBuffer(Buffer.from(hex, 'hex'));
+ return UniqueNote.fromBuffer(hexToBuffer(str));
}
}
diff --git a/yarn-project/circuit-types/src/p2p/consensus_payload.ts b/yarn-project/circuit-types/src/p2p/consensus_payload.ts
index a5ce2fbed50..3c4d5e946b0 100644
--- a/yarn-project/circuit-types/src/p2p/consensus_payload.ts
+++ b/yarn-project/circuit-types/src/p2p/consensus_payload.ts
@@ -1,6 +1,7 @@
import { Header } from '@aztec/circuits.js';
import { Fr } from '@aztec/foundation/fields';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
+import { hexToBuffer } from '@aztec/foundation/string';
import { type FieldsOf } from '@aztec/foundation/types';
import { encodeAbiParameters, parseAbiParameters } from 'viem';
@@ -26,19 +27,19 @@ export class ConsensusPayload implements Signable {
getPayloadToSign(domainSeperator: SignatureDomainSeperator): Buffer {
const abi = parseAbiParameters('uint8, (bytes32, bytes32, (uint256, uint256), bytes, bytes32[])');
- const txArray = this.txHashes.map(tx => tx.to0xString());
+ const txArray = this.txHashes.map(tx => tx.toString());
const encodedData = encodeAbiParameters(abi, [
domainSeperator,
[
this.archive.toString(),
this.header.hash().toString(),
[0n, 0n] /* @todo See #9963 */,
- `0x${this.header.toString()}`,
+ this.header.toString(),
txArray,
],
] as const);
- return Buffer.from(encodedData.slice(2), 'hex');
+ return hexToBuffer(encodedData);
}
toBuffer(): Buffer {
diff --git a/yarn-project/circuit-types/src/private_execution_result.test.ts b/yarn-project/circuit-types/src/private_execution_result.test.ts
index f67092467df..1b3a97f766e 100644
--- a/yarn-project/circuit-types/src/private_execution_result.test.ts
+++ b/yarn-project/circuit-types/src/private_execution_result.test.ts
@@ -1,5 +1,5 @@
import { Fr, PrivateCircuitPublicInputs } from '@aztec/circuits.js';
-import { jsonStringify } from '@aztec/foundation/json-rpc';
+import { jsonParseWithSchema, jsonStringify } from '@aztec/foundation/json-rpc';
import {
PrivateExecutionResult,
@@ -36,8 +36,11 @@ describe('execution_result', () => {
});
describe('serialization', () => {
- const instance = PrivateExecutionResult.random();
- expect(PrivateExecutionResult.schema.parse(JSON.parse(jsonStringify(instance)))).toEqual(instance);
+ it('serializes and deserializes correctly', () => {
+ const instance = PrivateExecutionResult.random();
+ jsonParseWithSchema;
+ expect(jsonParseWithSchema(jsonStringify(instance), PrivateExecutionResult.schema)).toEqual(instance);
+ });
});
describe('collectNoteHashLeafIndexMap', () => {
diff --git a/yarn-project/circuit-types/src/private_execution_result.ts b/yarn-project/circuit-types/src/private_execution_result.ts
index 588c4c44ab2..893ecc0ad4f 100644
--- a/yarn-project/circuit-types/src/private_execution_result.ts
+++ b/yarn-project/circuit-types/src/private_execution_result.ts
@@ -3,7 +3,7 @@ import { NoteSelector } from '@aztec/foundation/abi';
import { times } from '@aztec/foundation/collection';
import { randomBytes, randomInt } from '@aztec/foundation/crypto';
import { Fr } from '@aztec/foundation/fields';
-import { type ZodFor, hexSchemaFor, mapSchema, schemas } from '@aztec/foundation/schemas';
+import { type ZodFor, mapSchema, schemas } from '@aztec/foundation/schemas';
import { type FieldsOf } from '@aztec/foundation/types';
import { z } from 'zod';
@@ -46,22 +46,6 @@ export class NoteAndSlot {
return new NoteAndSlot(fields.note, fields.storageSlot, fields.noteTypeId);
}
- toJSON() {
- return {
- note: this.note.toBuffer().toString('hex'),
- storageSlot: this.storageSlot.toBuffer().toString('hex'),
- noteTypeId: this.noteTypeId.toString(),
- };
- }
-
- public static fromJSON(json: any): NoteAndSlot {
- return new NoteAndSlot(
- Note.fromBuffer(Buffer.from(json.note, 'hex')),
- Fr.fromString(json.storageSlot),
- NoteSelector.fromString(json.noteTypeId),
- );
- }
-
static random() {
return new NoteAndSlot(Note.random(), Fr.random(), NoteSelector.random());
}
@@ -115,18 +99,6 @@ export class CountedNoteLog extends CountedLog {
.transform(({ log, counter, noteHashCounter }) => new CountedNoteLog(log, counter, noteHashCounter));
}
- toJSON() {
- return {
- log: this.log.toJSON(),
- counter: this.counter,
- noteHashCounter: this.noteHashCounter,
- };
- }
-
- static fromJSON(json: any) {
- return new CountedNoteLog(EncryptedL2NoteLog.fromJSON(json.log), json.counter, json.noteHashCounter);
- }
-
static random() {
return new CountedNoteLog(EncryptedL2NoteLog.random(), randomInt(10), randomInt(10));
}
@@ -138,7 +110,7 @@ export class CountedPublicExecutionRequest {
static get schema() {
return z
.object({
- request: hexSchemaFor(PublicExecutionRequest), // TODO(palla/schema) Use PublicExecutionRequest.schema,
+ request: PublicExecutionRequest.schema,
counter: schemas.Integer,
})
.transform(CountedPublicExecutionRequest.from);
@@ -152,20 +124,6 @@ export class CountedPublicExecutionRequest {
return this.request.isEmpty() && !this.counter;
}
- toJSON() {
- return {
- request: this.request.toBuffer().toString('hex'),
- counter: this.counter,
- };
- }
-
- static fromJSON(json: any) {
- return new CountedPublicExecutionRequest(
- PublicExecutionRequest.fromBuffer(Buffer.from(json.request, 'hex')),
- json.counter,
- );
- }
-
static random() {
return new CountedPublicExecutionRequest(PublicExecutionRequest.random(), 0);
}
@@ -220,8 +178,8 @@ export class PrivateExecutionResult {
static get schema(): ZodFor {
return z
.object({
- acir: schemas.BufferHex,
- vk: schemas.BufferHex,
+ acir: schemas.Buffer,
+ vk: schemas.Buffer,
partialWitness: mapSchema(z.coerce.number(), z.string()),
publicInputs: PrivateCircuitPublicInputs.schema,
noteHashLeafIndexMap: mapSchema(schemas.BigInt, schemas.BigInt),
@@ -230,7 +188,7 @@ export class PrivateExecutionResult {
returnValues: z.array(schemas.Fr),
nestedExecutions: z.array(z.lazy(() => PrivateExecutionResult.schema)),
enqueuedPublicFunctionCalls: z.array(CountedPublicExecutionRequest.schema),
- publicTeardownFunctionCall: hexSchemaFor(PublicExecutionRequest), // TODO(palla/schema) Use PublicExecutionRequest.schema
+ publicTeardownFunctionCall: PublicExecutionRequest.schema,
noteEncryptedLogs: z.array(CountedNoteLog.schema),
encryptedLogs: z.array(CountedLog.schemaFor(EncryptedL2Log)),
contractClassLogs: z.array(CountedLog.schemaFor(UnencryptedL2Log)),
@@ -257,34 +215,6 @@ export class PrivateExecutionResult {
);
}
- toJSON(): any {
- return {
- acir: this.acir.toString('hex'),
- vk: this.vk.toString('hex'),
- partialWitness: Array.from(this.partialWitness.entries()),
- publicInputs: this.publicInputs.toJSON(),
- noteHashLeafIndexMap: Array.from(this.noteHashLeafIndexMap.entries()).map(([key, value]) => [
- key.toString(),
- value.toString(),
- ]),
- newNotes: this.newNotes.map(note => note.toJSON()),
- noteHashNullifierCounterMap: Array.from(this.noteHashNullifierCounterMap.entries()),
- returnValues: this.returnValues.map(fr => fr.toBuffer().toString('hex')),
- nestedExecutions: this.nestedExecutions.map(exec => exec.toJSON()),
- enqueuedPublicFunctionCalls: this.enqueuedPublicFunctionCalls.map(call => call.toJSON()),
- publicTeardownFunctionCall: this.publicTeardownFunctionCall.toBuffer().toString('hex'),
- noteEncryptedLogs: this.noteEncryptedLogs.map(log => log.toJSON()),
- encryptedLogs: this.encryptedLogs.map(countedLog => ({
- log: countedLog.log.toJSON(),
- counter: countedLog.counter,
- })),
- contractClassLogs: this.contractClassLogs.map(countedLog => ({
- log: countedLog.log.toJSON(),
- counter: countedLog.counter,
- })),
- };
- }
-
static random(nested = 1): PrivateExecutionResult {
return new PrivateExecutionResult(
randomBytes(4),
@@ -303,45 +233,6 @@ export class PrivateExecutionResult {
[new CountedLog(UnencryptedL2Log.random(), randomInt(10))],
);
}
-
- static fromJSON(json: any): PrivateExecutionResult {
- return new PrivateExecutionResult(
- Buffer.from(json.acir, 'hex'),
- Buffer.from(json.vk, 'hex'),
- Array.isArray(json.partialWitness)
- ? new Map(json.partialWitness.map(([key, value]: any[]) => [Number(key), value as string]))
- : new Map(),
- PrivateCircuitPublicInputs.fromJSON(json.publicInputs),
- Array.isArray(json.noteHashLeafIndexMap)
- ? new Map(json.noteHashLeafIndexMap.map(([key, value]: any[]) => [BigInt(key), BigInt(value)]))
- : new Map(),
- Array.isArray(json.newNotes) ? json.newNotes.map((note: any) => NoteAndSlot.fromJSON(note)) : [],
- Array.isArray(json.noteHashNullifierCounterMap)
- ? new Map(json.noteHashNullifierCounterMap.map(([key, value]: any[]) => [Number(key), Number(value)]))
- : new Map(),
- json.returnValues.map((fr: any) => new Fr(Buffer.from(fr, 'hex'))),
- Array.isArray(json.nestedExecutions)
- ? json.nestedExecutions.map((exec: any) => PrivateExecutionResult.fromJSON(exec))
- : [],
- Array.isArray(json.enqueuedPublicFunctionCalls)
- ? json.enqueuedPublicFunctionCalls.map((call: any) => CountedPublicExecutionRequest.fromJSON(call))
- : [],
- PublicExecutionRequest.fromBuffer(Buffer.from(json.publicTeardownFunctionCall, 'hex')),
- Array.isArray(json.noteEncryptedLogs)
- ? json.noteEncryptedLogs.map((json: any) => CountedNoteLog.fromJSON(json))
- : [],
- Array.isArray(json.encryptedLogs)
- ? json.encryptedLogs.map(
- (json: any) => new CountedLog(EncryptedL2Log.fromJSON(json.log), json.counter),
- )
- : [],
- Array.isArray(json.contractClassLogs)
- ? json.contractClassLogs.map(
- (json: any) => new CountedLog(UnencryptedL2Log.fromJSON(json.log), json.counter),
- )
- : [],
- );
- }
}
export function collectNoteHashLeafIndexMap(
diff --git a/yarn-project/circuit-types/src/prover_coordination/epoch_proof_quote.test.ts b/yarn-project/circuit-types/src/prover_coordination/epoch_proof_quote.test.ts
index 78f68edee04..fe29fcb941d 100644
--- a/yarn-project/circuit-types/src/prover_coordination/epoch_proof_quote.test.ts
+++ b/yarn-project/circuit-types/src/prover_coordination/epoch_proof_quote.test.ts
@@ -1,5 +1,6 @@
import { EthAddress } from '@aztec/circuits.js';
import { Signature } from '@aztec/foundation/eth-signature';
+import { jsonParseWithSchema, jsonStringify } from '@aztec/foundation/json-rpc';
import { EpochProofQuote } from './epoch_proof_quote.js';
import { EpochProofQuotePayload } from './epoch_proof_quote_payload.js';
@@ -30,7 +31,7 @@ describe('epoch proof quote', () => {
});
it('should serialize and deserialize from JSON', () => {
- const deserialised = EpochProofQuote.fromJSON(quote.toJSON());
+ const deserialised = jsonParseWithSchema(jsonStringify(quote), EpochProofQuote.schema);
checkEquivalence(quote, deserialised);
});
});
diff --git a/yarn-project/circuit-types/src/prover_coordination/epoch_proof_quote.ts b/yarn-project/circuit-types/src/prover_coordination/epoch_proof_quote.ts
index d6f7222cf8b..454d01aa585 100644
--- a/yarn-project/circuit-types/src/prover_coordination/epoch_proof_quote.ts
+++ b/yarn-project/circuit-types/src/prover_coordination/epoch_proof_quote.ts
@@ -1,7 +1,6 @@
import { Buffer32 } from '@aztec/foundation/buffer';
import { type Secp256k1Signer, keccak256 } from '@aztec/foundation/crypto';
import { Signature } from '@aztec/foundation/eth-signature';
-import { schemas } from '@aztec/foundation/schemas';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
import { type FieldsOf } from '@aztec/foundation/types';
@@ -44,26 +43,15 @@ export class EpochProofQuote extends Gossipable {
return new EpochProofQuote(reader.readObject(EpochProofQuotePayload), reader.readObject(Signature));
}
- toJSON() {
- return {
- payload: this.payload.toJSON(),
- signature: this.signature.to0xString(),
- };
- }
-
static get schema() {
return z
.object({
payload: EpochProofQuotePayload.schema,
- signature: schemas.Signature,
+ signature: Signature.schema,
})
.transform(({ payload, signature }) => new EpochProofQuote(payload, signature));
}
- static fromJSON(obj: any) {
- return EpochProofQuote.schema.parse(obj);
- }
-
// TODO: https://github.com/AztecProtocol/aztec-packages/issues/8911
/**
* Creates a new quote with a signature.
diff --git a/yarn-project/circuit-types/src/prover_coordination/epoch_proof_quote_payload.ts b/yarn-project/circuit-types/src/prover_coordination/epoch_proof_quote_payload.ts
index 7f1e87eee87..60c06e39501 100644
--- a/yarn-project/circuit-types/src/prover_coordination/epoch_proof_quote_payload.ts
+++ b/yarn-project/circuit-types/src/prover_coordination/epoch_proof_quote_payload.ts
@@ -3,6 +3,7 @@ import { schemas } from '@aztec/foundation/schemas';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
import { type FieldsOf } from '@aztec/foundation/types';
+import omit from 'lodash.omit';
import { inspect } from 'util';
import { z } from 'zod';
@@ -82,31 +83,21 @@ export class EpochProofQuotePayload {
}
toJSON() {
- return {
- epochToProve: this.epochToProve.toString(),
- validUntilSlot: this.validUntilSlot.toString(),
- bondAmount: this.bondAmount.toString(),
- prover: this.prover.toString(),
- basisPointFee: this.basisPointFee,
- };
+ return omit(this, 'asBuffer', 'size');
}
static get schema() {
return z
.object({
- epochToProve: z.coerce.bigint(),
- validUntilSlot: z.coerce.bigint(),
- bondAmount: z.coerce.bigint(),
+ epochToProve: schemas.BigInt,
+ validUntilSlot: schemas.BigInt,
+ bondAmount: schemas.BigInt,
prover: schemas.EthAddress,
- basisPointFee: z.number(),
+ basisPointFee: schemas.Integer,
})
.transform(EpochProofQuotePayload.from);
}
- static fromJSON(obj: any): EpochProofQuotePayload {
- return EpochProofQuotePayload.schema.parse(obj);
- }
-
toViemArgs(): {
epochToProve: bigint;
validUntilSlot: bigint;
diff --git a/yarn-project/circuit-types/src/public_data_witness.ts b/yarn-project/circuit-types/src/public_data_witness.ts
index cdc33705231..41e43418b9a 100644
--- a/yarn-project/circuit-types/src/public_data_witness.ts
+++ b/yarn-project/circuit-types/src/public_data_witness.ts
@@ -2,6 +2,7 @@ import { Fr, PUBLIC_DATA_TREE_HEIGHT, PublicDataTreeLeafPreimage } from '@aztec/
import { toBigIntBE } from '@aztec/foundation/bigint-buffer';
import { schemas } from '@aztec/foundation/schemas';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { z } from 'zod';
@@ -63,7 +64,7 @@ export class PublicDataWitness {
* Returns a string representation of the TxEffect object.
*/
toString(): string {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
static random() {
@@ -95,6 +96,6 @@ export class PublicDataWitness {
* @returns An instance of PublicDataWitness.
*/
static fromString(str: string) {
- return PublicDataWitness.fromBuffer(Buffer.from(str, 'hex'));
+ return PublicDataWitness.fromBuffer(hexToBuffer(str));
}
}
diff --git a/yarn-project/circuit-types/src/public_execution_request.ts b/yarn-project/circuit-types/src/public_execution_request.ts
index 7cf834cb1c8..6371bac3b09 100644
--- a/yarn-project/circuit-types/src/public_execution_request.ts
+++ b/yarn-project/circuit-types/src/public_execution_request.ts
@@ -40,13 +40,6 @@ export class PublicExecutionRequest {
.transform(PublicExecutionRequest.from);
}
- toJSON() {
- return {
- callContext: this.callContext,
- args: this.args,
- };
- }
-
static fromBuffer(buffer: Buffer | BufferReader) {
const reader = BufferReader.asReader(buffer);
return new PublicExecutionRequest(CallContext.fromBuffer(reader), reader.readVector(Fr));
diff --git a/yarn-project/circuit-types/src/sibling_path/sibling_path.test.ts b/yarn-project/circuit-types/src/sibling_path/sibling_path.test.ts
new file mode 100644
index 00000000000..d48e32e820b
--- /dev/null
+++ b/yarn-project/circuit-types/src/sibling_path/sibling_path.test.ts
@@ -0,0 +1,19 @@
+import { jsonStringify } from '@aztec/foundation/json-rpc';
+
+import { SiblingPath } from './sibling_path.js';
+
+describe('SiblingPath', () => {
+ it('serializes to JSON', () => {
+ const path = SiblingPath.random(10);
+ const json = jsonStringify(path);
+ expect(SiblingPath.schema.parse(JSON.parse(json))).toEqual(path);
+ });
+
+ it('validates length', () => {
+ const path = SiblingPath.random(10);
+ const json = jsonStringify(path);
+ expect(() => SiblingPath.schemaFor(12).parse(JSON.parse(json))).toThrow(
+ expect.objectContaining({ name: 'ZodError' }),
+ );
+ });
+});
diff --git a/yarn-project/circuit-types/src/sibling_path/sibling_path.ts b/yarn-project/circuit-types/src/sibling_path/sibling_path.ts
index a18d02ce951..96738dab368 100644
--- a/yarn-project/circuit-types/src/sibling_path/sibling_path.ts
+++ b/yarn-project/circuit-types/src/sibling_path/sibling_path.ts
@@ -1,12 +1,13 @@
import { makeTuple } from '@aztec/foundation/array';
import { Fr } from '@aztec/foundation/fields';
-import { hexSchema, hexSchemaFor } from '@aztec/foundation/schemas';
+import { schemas } from '@aztec/foundation/schemas';
import {
type Tuple,
assertLength,
deserializeArrayFromVector,
serializeArrayOfBufferableToVector,
} from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { type Hasher } from '@aztec/types/interfaces';
/**
@@ -37,17 +38,18 @@ export class SiblingPath {
}
static get schema() {
- return hexSchemaFor(SiblingPath);
+ return schemas.Buffer.transform(b => SiblingPath.fromBuffer(b));
}
static schemaFor(size: N) {
- return hexSchema
- .transform(str => SiblingPath.fromString(str) as SiblingPath)
- .refine(path => path.pathSize === size, 'Unexpected size');
+ return schemas.Buffer.transform(b => SiblingPath.fromBuffer(b) as SiblingPath).refine(
+ path => path.pathSize === size,
+ path => ({ message: `Expected sibling path size ${size} but got ${path.pathSize}` }),
+ );
}
toJSON() {
- return this.toString();
+ return this.toBuffer();
}
/**
@@ -137,7 +139,7 @@ export class SiblingPath {
* @returns A hex string representation of the sibling path.
*/
public toString(): string {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
/**
@@ -146,7 +148,7 @@ export class SiblingPath {
* @returns A SiblingPath object.
*/
public static fromString(repr: string): SiblingPath {
- return SiblingPath.fromBuffer(Buffer.from(repr, 'hex'));
+ return SiblingPath.fromBuffer(hexToBuffer(repr));
}
/**
diff --git a/yarn-project/circuit-types/src/simulation_error.ts b/yarn-project/circuit-types/src/simulation_error.ts
index 70cd960217a..3e84bbdb60e 100644
--- a/yarn-project/circuit-types/src/simulation_error.ts
+++ b/yarn-project/circuit-types/src/simulation_error.ts
@@ -1,4 +1,4 @@
-import { AztecAddress, Fr, FunctionSelector } from '@aztec/circuits.js';
+import { AztecAddress, type Fr, FunctionSelector } from '@aztec/circuits.js';
import { type OpcodeLocation } from '@aztec/foundation/abi';
import { schemas } from '@aztec/foundation/schemas';
@@ -220,15 +220,6 @@ export class SimulationError extends Error {
};
}
- static fromJSON(obj: ReturnType) {
- return new SimulationError(
- obj.originalMessage,
- obj.functionErrorStack,
- obj.revertData.map(serializedFr => Fr.fromString(serializedFr)),
- obj.noirErrorStack,
- );
- }
-
static get schema() {
return z
.object({
diff --git a/yarn-project/circuit-types/src/tx/block_hash.ts b/yarn-project/circuit-types/src/tx/block_hash.ts
new file mode 100644
index 00000000000..010b2e6ca16
--- /dev/null
+++ b/yarn-project/circuit-types/src/tx/block_hash.ts
@@ -0,0 +1,29 @@
+import { Fr } from '@aztec/circuits.js';
+import { Buffer32 } from '@aztec/foundation/buffer';
+import { schemas } from '@aztec/foundation/schemas';
+
+/** Hash of an L2 block. */
+export class L2BlockHash extends Buffer32 {
+ constructor(
+ /** The buffer containing the hash. */
+ hash: Buffer,
+ ) {
+ super(hash);
+ }
+
+ static override random() {
+ return new L2BlockHash(Fr.random().toBuffer());
+ }
+
+ static get schema() {
+ return schemas.BufferHex.transform(value => new L2BlockHash(value));
+ }
+
+ static zero() {
+ return new L2BlockHash(Buffer32.ZERO.toBuffer());
+ }
+
+ static override fromField(hash: Fr) {
+ return new L2BlockHash(hash.toBuffer());
+ }
+}
diff --git a/yarn-project/circuit-types/src/tx/index.ts b/yarn-project/circuit-types/src/tx/index.ts
index bc94339f36b..30cae14ee88 100644
--- a/yarn-project/circuit-types/src/tx/index.ts
+++ b/yarn-project/circuit-types/src/tx/index.ts
@@ -7,3 +7,4 @@ export * from './tx_hash.js';
export * from './tx_receipt.js';
export * from './validator/tx_validator.js';
export * from './validator/empty_validator.js';
+export * from './block_hash.js';
diff --git a/yarn-project/circuit-types/src/tx/public_simulation_output.test.ts b/yarn-project/circuit-types/src/tx/public_simulation_output.test.ts
new file mode 100644
index 00000000000..8582164a408
--- /dev/null
+++ b/yarn-project/circuit-types/src/tx/public_simulation_output.test.ts
@@ -0,0 +1,11 @@
+import { jsonStringify } from '@aztec/foundation/json-rpc';
+
+import { PublicSimulationOutput } from './public_simulation_output.js';
+
+describe('PublicSimulationOutput', () => {
+ it('serializes to JSON', () => {
+ const output = PublicSimulationOutput.random();
+ const json = jsonStringify(output);
+ expect(PublicSimulationOutput.schema.parse(JSON.parse(json))).toEqual(output);
+ });
+});
diff --git a/yarn-project/circuit-types/src/tx/public_simulation_output.ts b/yarn-project/circuit-types/src/tx/public_simulation_output.ts
index a6748c071aa..98ca5e8fc60 100644
--- a/yarn-project/circuit-types/src/tx/public_simulation_output.ts
+++ b/yarn-project/circuit-types/src/tx/public_simulation_output.ts
@@ -1,5 +1,4 @@
import { CombinedConstantData, Fr, Gas } from '@aztec/circuits.js';
-import { mapValues } from '@aztec/foundation/collection';
import { type ZodFor, schemas } from '@aztec/foundation/schemas';
import times from 'lodash.times';
@@ -31,20 +30,6 @@ export class NestedProcessReturnValues {
.transform(({ values, nested }) => new NestedProcessReturnValues(values, nested));
}
- toJSON(): any {
- return {
- values: this.values?.map(fr => fr.toString()),
- nested: this.nested.map(n => n.toJSON()),
- };
- }
-
- static fromJSON(json: any): NestedProcessReturnValues {
- return new NestedProcessReturnValues(
- json.values?.map(Fr.fromString),
- json.nested?.map((n: any) => NestedProcessReturnValues.fromJSON(n)),
- );
- }
-
static empty() {
return new NestedProcessReturnValues([]);
}
@@ -90,28 +75,6 @@ export class PublicSimulationOutput {
);
}
- toJSON() {
- return {
- revertReason: this.revertReason,
- constants: this.constants.toBuffer().toString('hex'),
- txEffect: this.txEffect.toBuffer().toString('hex'),
- publicReturnValues: this.publicReturnValues.map(returns => returns?.toJSON()),
- gasUsed: mapValues(this.gasUsed, gas => gas?.toJSON()),
- };
- }
-
- static fromJSON(json: any): PublicSimulationOutput {
- return new PublicSimulationOutput(
- json.revertReason,
- CombinedConstantData.fromBuffer(Buffer.from(json.constants, 'hex')),
- TxEffect.fromBuffer(Buffer.from(json.txEffect, 'hex')),
- Array.isArray(json.publicReturnValues)
- ? json.publicReturnValues.map((returns: any) => NestedProcessReturnValues.fromJSON(returns))
- : [],
- mapValues(json.gasUsed, gas => Gas.fromJSON(gas)),
- );
- }
-
static random() {
return new PublicSimulationOutput(
SimulationError.random(),
diff --git a/yarn-project/circuit-types/src/tx/simulated_tx.test.ts b/yarn-project/circuit-types/src/tx/simulated_tx.test.ts
index 035bab4f517..a12a51e3452 100644
--- a/yarn-project/circuit-types/src/tx/simulated_tx.test.ts
+++ b/yarn-project/circuit-types/src/tx/simulated_tx.test.ts
@@ -1,18 +1,33 @@
+import { jsonStringify } from '@aztec/foundation/json-rpc';
+
import { mockSimulatedTx } from '../mocks.js';
-import { TxSimulationResult } from './simulated_tx.js';
+import { TxProvingResult, TxSimulationResult } from './simulated_tx.js';
describe('simulated_tx', () => {
- let simulatedTx: TxSimulationResult;
- beforeEach(() => {
- simulatedTx = mockSimulatedTx();
- });
- describe('json', () => {
+ describe('TxSimulationResult', () => {
+ let simulatedTx: TxSimulationResult;
+ beforeEach(() => {
+ simulatedTx = mockSimulatedTx();
+ });
+
it('convert to and from json', () => {
- expect(TxSimulationResult.fromJSON(JSON.parse(JSON.stringify(simulatedTx.toJSON())))).toEqual(simulatedTx);
+ expect(TxSimulationResult.schema.parse(JSON.parse(jsonStringify(simulatedTx)))).toEqual(simulatedTx);
});
+
it('convert undefined effects to and from json', () => {
simulatedTx.publicOutput = undefined;
- expect(TxSimulationResult.fromJSON(JSON.parse(JSON.stringify(simulatedTx.toJSON())))).toEqual(simulatedTx);
+ expect(TxSimulationResult.schema.parse(JSON.parse(jsonStringify(simulatedTx)))).toEqual(simulatedTx);
+ });
+ });
+
+ describe('TxProvingResult', () => {
+ let tx: TxProvingResult;
+ beforeEach(() => {
+ tx = TxProvingResult.random();
+ });
+
+ it('convert to and from json', () => {
+ expect(TxProvingResult.schema.parse(JSON.parse(jsonStringify(tx)))).toEqual(tx);
});
});
});
diff --git a/yarn-project/circuit-types/src/tx/simulated_tx.ts b/yarn-project/circuit-types/src/tx/simulated_tx.ts
index 62c6270908c..f53e55e2923 100644
--- a/yarn-project/circuit-types/src/tx/simulated_tx.ts
+++ b/yarn-project/circuit-types/src/tx/simulated_tx.ts
@@ -55,19 +55,6 @@ export class PrivateSimulationResult {
);
return tx;
}
-
- public toJSON() {
- return {
- privateExecutionResult: this.privateExecutionResult.toJSON(),
- publicInputs: this.publicInputs.toBuffer().toString('hex'),
- };
- }
-
- public static fromJSON(obj: any) {
- const privateExecutionResult = PrivateExecutionResult.fromJSON(obj.privateExecutionResult);
- const publicInputs = PrivateKernelTailCircuitPublicInputs.fromBuffer(Buffer.from(obj.publicInputs, 'hex'));
- return new PrivateSimulationResult(privateExecutionResult, publicInputs);
- }
}
export class TxSimulationResult extends PrivateSimulationResult {
@@ -126,21 +113,12 @@ export class TxSimulationResult extends PrivateSimulationResult {
);
}
- public override toJSON() {
- return {
- privateExecutionResult: this.privateExecutionResult.toJSON(),
- publicInputs: this.publicInputs.toBuffer().toString('hex'),
- publicOutput: this.publicOutput ? this.publicOutput.toJSON() : undefined,
- profileResult: this.profileResult,
- };
- }
-
- public static override fromJSON(obj: any) {
- const privateExecutionResult = PrivateExecutionResult.fromJSON(obj.privateExecutionResult);
- const publicInputs = PrivateKernelTailCircuitPublicInputs.fromBuffer(Buffer.from(obj.publicInputs, 'hex'));
- const publicOuput = obj.publicOutput ? PublicSimulationOutput.fromJSON(obj.publicOutput) : undefined;
- const profileResult = obj.profileResult;
- return new TxSimulationResult(privateExecutionResult, publicInputs, publicOuput, profileResult);
+ static random() {
+ return new TxSimulationResult(
+ PrivateExecutionResult.random(),
+ PrivateKernelTailCircuitPublicInputs.empty(),
+ PublicSimulationOutput.random(),
+ );
}
}
@@ -186,19 +164,12 @@ export class TxProvingResult {
return new TxProvingResult(fields.privateExecutionResult, fields.publicInputs, fields.clientIvcProof);
}
- public toJSON() {
- return {
- privateExecutionResult: this.privateExecutionResult,
- publicInputs: this.publicInputs,
- clientIvcProof: this.clientIvcProof,
- };
- }
-
- public static fromJSON(obj: any) {
- const privateExecutionResult = PrivateExecutionResult.fromJSON(obj.privateExecutionResult);
- const publicInputs = PrivateKernelTailCircuitPublicInputs.fromBuffer(Buffer.from(obj.publicInputs, 'hex'));
- const clientIvcProof = ClientIvcProof.fromBuffer(Buffer.from(obj.clientIvcProof, 'hex'));
- return new TxProvingResult(privateExecutionResult, publicInputs, clientIvcProof);
+ static random() {
+ return new TxProvingResult(
+ PrivateExecutionResult.random(),
+ PrivateKernelTailCircuitPublicInputs.empty(),
+ ClientIvcProof.empty(),
+ );
}
}
diff --git a/yarn-project/circuit-types/src/tx/tx.test.ts b/yarn-project/circuit-types/src/tx/tx.test.ts
index 3cfe2c1a4eb..0710303b16b 100644
--- a/yarn-project/circuit-types/src/tx/tx.test.ts
+++ b/yarn-project/circuit-types/src/tx/tx.test.ts
@@ -1,3 +1,5 @@
+import { jsonStringify } from '@aztec/foundation/json-rpc';
+
import { mockTx } from '../mocks.js';
import { Tx } from './tx.js';
@@ -7,4 +9,10 @@ describe('Tx', () => {
const buf = tx.toBuffer();
expect(Tx.fromBuffer(buf)).toEqual(tx);
});
+
+ it('convert to and from json', () => {
+ const tx = mockTx();
+ const json = jsonStringify(tx);
+ expect(Tx.schema.parse(JSON.parse(json))).toEqual(tx);
+ });
});
diff --git a/yarn-project/circuit-types/src/tx/tx.ts b/yarn-project/circuit-types/src/tx/tx.ts
index e290ad2a46f..d049697cec3 100644
--- a/yarn-project/circuit-types/src/tx/tx.ts
+++ b/yarn-project/circuit-types/src/tx/tx.ts
@@ -7,8 +7,8 @@ import {
} from '@aztec/circuits.js';
import { type Buffer32 } from '@aztec/foundation/buffer';
import { arraySerializedSizeOfNonEmpty } from '@aztec/foundation/collection';
-import { hexSchema } from '@aztec/foundation/schemas';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
+import { type FieldsOf } from '@aztec/foundation/types';
import { z } from 'zod';
@@ -154,65 +154,30 @@ export class Tx extends Gossipable {
}
static get schema() {
- // TODO(palla/schemas): Use the nested objects schemas as opposed to the toBuffers
return z
.object({
- data: hexSchema, // PrivateKernelTailCircuitPublicInputs.schema,
- clientIvcProof: hexSchema, // ClientIvcProof.schema,
- noteEncryptedLogs: hexSchema, // EncryptedNoteTxL2Logs.schema,
- encryptedLogs: hexSchema, // EncryptedTxL2Logs.schema,
- unencryptedLogs: hexSchema, // UnencryptedTxL2Logs.schema,
- contractClassLogs: hexSchema, // ContractClassTxL2Logs.schema,
- enqueuedPublicFunctionCalls: z.array(hexSchema), // z.array(PublicExecutionRequest.schema),
- publicTeardownFunctionCall: hexSchema, // PublicExecutionRequest.schema,
+ data: PrivateKernelTailCircuitPublicInputs.schema,
+ clientIvcProof: ClientIvcProof.schema,
+ noteEncryptedLogs: EncryptedNoteTxL2Logs.schema,
+ encryptedLogs: EncryptedTxL2Logs.schema,
+ unencryptedLogs: UnencryptedTxL2Logs.schema,
+ contractClassLogs: ContractClassTxL2Logs.schema,
+ enqueuedPublicFunctionCalls: z.array(PublicExecutionRequest.schema),
+ publicTeardownFunctionCall: PublicExecutionRequest.schema,
})
- .transform(Tx.fromJSON);
+ .transform(Tx.from);
}
- /**
- * Convert a Tx class object to a plain JSON object.
- * @returns A plain object with Tx properties.
- */
- public toJSON() {
- return {
- data: this.data.toBuffer().toString('hex'),
- noteEncryptedLogs: this.noteEncryptedLogs.toBuffer().toString('hex'),
- encryptedLogs: this.encryptedLogs.toBuffer().toString('hex'),
- unencryptedLogs: this.unencryptedLogs.toBuffer().toString('hex'),
- contractClassLogs: this.contractClassLogs.toBuffer().toString('hex'),
- clientIvcProof: this.clientIvcProof.toBuffer().toString('hex'),
- enqueuedPublicFunctionCalls: this.enqueuedPublicFunctionCalls.map(f => f.toBuffer().toString('hex')) ?? [],
- publicTeardownFunctionCall: this.publicTeardownFunctionCall.toBuffer().toString('hex'),
- };
- }
-
- /**
- * Convert a plain JSON object to a Tx class object.
- * @param obj - A plain Tx JSON object.
- * @returns A Tx class object.
- */
- public static fromJSON(obj: any) {
- const publicInputs = PrivateKernelTailCircuitPublicInputs.fromBuffer(Buffer.from(obj.data, 'hex'));
- const noteEncryptedLogs = EncryptedNoteTxL2Logs.fromBuffer(Buffer.from(obj.noteEncryptedLogs, 'hex'));
- const encryptedLogs = EncryptedTxL2Logs.fromBuffer(Buffer.from(obj.encryptedLogs, 'hex'));
- const unencryptedLogs = UnencryptedTxL2Logs.fromBuffer(Buffer.from(obj.unencryptedLogs, 'hex'));
- const contractClassLogs = ContractClassTxL2Logs.fromBuffer(Buffer.from(obj.contractClassLogs, 'hex'));
- const clientIvcProof = ClientIvcProof.fromBuffer(Buffer.from(obj.clientIvcProof, 'hex'));
- const enqueuedPublicFunctionCalls = obj.enqueuedPublicFunctionCalls
- ? obj.enqueuedPublicFunctionCalls.map((x: string) => PublicExecutionRequest.fromBuffer(Buffer.from(x, 'hex')))
- : [];
- const publicTeardownFunctionCall = PublicExecutionRequest.fromBuffer(
- Buffer.from(obj.publicTeardownFunctionCall, 'hex'),
- );
+ static from(fields: FieldsOf) {
return new Tx(
- publicInputs,
- clientIvcProof,
- noteEncryptedLogs,
- encryptedLogs,
- unencryptedLogs,
- contractClassLogs,
- enqueuedPublicFunctionCalls,
- publicTeardownFunctionCall,
+ fields.data,
+ fields.clientIvcProof,
+ fields.noteEncryptedLogs,
+ fields.encryptedLogs,
+ fields.unencryptedLogs,
+ fields.contractClassLogs,
+ fields.enqueuedPublicFunctionCalls,
+ fields.publicTeardownFunctionCall,
);
}
diff --git a/yarn-project/circuit-types/src/tx/tx_receipt.test.ts b/yarn-project/circuit-types/src/tx/tx_receipt.test.ts
index 2eac60ece2e..b55ec33b7a8 100644
--- a/yarn-project/circuit-types/src/tx/tx_receipt.test.ts
+++ b/yarn-project/circuit-types/src/tx/tx_receipt.test.ts
@@ -1,3 +1,6 @@
+import { jsonStringify } from '@aztec/foundation/json-rpc';
+
+import { L2BlockHash } from './block_hash.js';
import { TxHash } from './tx_hash.js';
import { TxReceipt, TxStatus } from './tx_receipt.js';
@@ -8,16 +11,16 @@ describe('TxReceipt', () => {
TxStatus.SUCCESS,
'error',
BigInt(1),
- Buffer.from('blockHash'),
+ L2BlockHash.random(),
undefined,
);
- expect(TxReceipt.fromJSON(receipt.toJSON())).toEqual(receipt);
+ expect(TxReceipt.schema.parse(JSON.parse(jsonStringify(receipt)))).toEqual(receipt);
});
it('serializes and deserializes from json with undefined fields', () => {
const receipt = new TxReceipt(TxHash.random(), TxStatus.DROPPED, 'error', undefined, undefined, undefined);
- expect(TxReceipt.fromJSON(receipt.toJSON())).toEqual(receipt);
+ expect(TxReceipt.schema.parse(JSON.parse(jsonStringify(receipt)))).toEqual(receipt);
});
});
diff --git a/yarn-project/circuit-types/src/tx/tx_receipt.ts b/yarn-project/circuit-types/src/tx/tx_receipt.ts
index 280dae346b7..50b6c840086 100644
--- a/yarn-project/circuit-types/src/tx/tx_receipt.ts
+++ b/yarn-project/circuit-types/src/tx/tx_receipt.ts
@@ -5,6 +5,7 @@ import { type FieldsOf } from '@aztec/foundation/types';
import { z } from 'zod';
+import { L2BlockHash } from './block_hash.js';
import { TxHash } from './tx_hash.js';
/**
@@ -36,7 +37,7 @@ export class TxReceipt {
/** The transaction fee paid for the transaction. */
public transactionFee?: bigint,
/** The hash of the block containing the transaction. */
- public blockHash?: Buffer,
+ public blockHash?: L2BlockHash,
/** The block number in which the transaction was included. */
public blockNumber?: number,
/** Information useful for testing/debugging, set when test flag is set to true in `waitOpts`. */
@@ -47,29 +48,13 @@ export class TxReceipt {
return new TxReceipt(TxHash.zero(), TxStatus.DROPPED, '');
}
- /**
- * Convert a Tx class object to a plain JSON object.
- * @returns A plain object with Tx properties.
- */
- public toJSON() {
- return {
- txHash: this.txHash.toString(),
- status: this.status.toString(),
- error: this.error,
- blockHash: this.blockHash?.toString('hex'),
- blockNumber: this.blockNumber,
- transactionFee: this.transactionFee?.toString(),
- ...(this.debugInfo && { debugInfo: this.debugInfo }),
- };
- }
-
static get schema() {
return z
.object({
txHash: TxHash.schema,
status: z.nativeEnum(TxStatus),
error: z.string(),
- blockHash: schemas.BufferHex.optional(),
+ blockHash: L2BlockHash.schema.optional(),
blockNumber: z.number().optional(),
transactionFee: schemas.BigInt.optional(),
debugInfo: DebugInfoSchema.optional(),
@@ -89,21 +74,6 @@ export class TxReceipt {
);
}
- /**
- * Convert a plain JSON object to a Tx class object.
- * @param obj - A plain Tx JSON object.
- * @returns A Tx class object.
- */
- public static fromJSON(obj: any) {
- const txHash = TxHash.fromString(obj.txHash);
- const status = obj.status as TxStatus;
- const error = obj.error;
- const transactionFee = obj.transactionFee ? BigInt(obj.transactionFee) : undefined;
- const blockHash = obj.blockHash ? Buffer.from(obj.blockHash, 'hex') : undefined;
- const blockNumber = obj.blockNumber ? Number(obj.blockNumber) : undefined;
- return new TxReceipt(txHash, status, error, transactionFee, blockHash, blockNumber);
- }
-
public static statusFromRevertCode(revertCode: RevertCode) {
if (revertCode.equals(RevertCode.OK)) {
return TxStatus.SUCCESS;
diff --git a/yarn-project/circuit-types/src/tx_effect.ts b/yarn-project/circuit-types/src/tx_effect.ts
index 8a06a7fb09b..3a00f06c9a2 100644
--- a/yarn-project/circuit-types/src/tx_effect.ts
+++ b/yarn-project/circuit-types/src/tx_effect.ts
@@ -7,17 +7,22 @@ import {
PublicDataWrite,
RevertCode,
} from '@aztec/circuits.js';
-import { makeTuple } from '@aztec/foundation/array';
+import { type FieldsOf, makeTuple } from '@aztec/foundation/array';
import { padArrayEnd } from '@aztec/foundation/collection';
import { sha256Trunc } from '@aztec/foundation/crypto';
-import { hexSchemaFor } from '@aztec/foundation/schemas';
+import { jsonStringify } from '@aztec/foundation/json-rpc';
+import { schemas } from '@aztec/foundation/schemas';
import { BufferReader, serializeArrayOfBufferableToVector, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { inspect } from 'util';
+import { z } from 'zod';
import { ContractClassTxL2Logs, EncryptedNoteTxL2Logs, EncryptedTxL2Logs, UnencryptedTxL2Logs } from './logs/index.js';
import { TxHash } from './tx/tx_hash.js';
+export { RevertCodeEnum } from '@aztec/circuits.js';
+
export class TxEffect {
constructor(
/**
@@ -264,21 +269,51 @@ export class TxEffect {
}
/** Returns a hex representation of the TxEffect object. */
- toString(): string {
- return this.toBuffer().toString('hex');
+ toString() {
+ return bufferToHex(this.toBuffer());
}
- toJSON() {
- return this.toString();
+ static from(fields: Omit, 'txHash'>) {
+ return new TxEffect(
+ fields.revertCode,
+ fields.transactionFee,
+ fields.noteHashes,
+ fields.nullifiers,
+ fields.l2ToL1Msgs,
+ fields.publicDataWrites,
+ fields.noteEncryptedLogsLength,
+ fields.encryptedLogsLength,
+ fields.unencryptedLogsLength,
+ fields.contractClassLogsLength,
+ fields.noteEncryptedLogs,
+ fields.encryptedLogs,
+ fields.unencryptedLogs,
+ fields.contractClassLogs,
+ );
}
static get schema() {
- return hexSchemaFor(TxEffect);
+ return z
+ .object({
+ revertCode: RevertCode.schema,
+ transactionFee: schemas.Fr,
+ noteHashes: z.array(schemas.Fr),
+ nullifiers: z.array(schemas.Fr),
+ l2ToL1Msgs: z.array(schemas.Fr),
+ publicDataWrites: z.array(PublicDataWrite.schema),
+ noteEncryptedLogsLength: schemas.Fr,
+ encryptedLogsLength: schemas.Fr,
+ unencryptedLogsLength: schemas.Fr,
+ contractClassLogsLength: schemas.Fr,
+ noteEncryptedLogs: EncryptedNoteTxL2Logs.schema,
+ encryptedLogs: EncryptedTxL2Logs.schema,
+ unencryptedLogs: UnencryptedTxL2Logs.schema,
+ contractClassLogs: ContractClassTxL2Logs.schema,
+ })
+ .transform(TxEffect.from);
}
[inspect.custom]() {
- // print out the non-empty fields
-
return `TxEffect {
revertCode: ${this.revertCode},
transactionFee: ${this.transactionFee},
@@ -290,10 +325,10 @@ export class TxEffect {
encryptedLogsLength: ${this.encryptedLogsLength},
unencryptedLogsLength: ${this.unencryptedLogsLength},
contractClassLogsLength: ${this.contractClassLogsLength},
- noteEncryptedLogs: ${JSON.stringify(this.noteEncryptedLogs.toJSON())},
- encryptedLogs: ${JSON.stringify(this.encryptedLogs.toJSON())},
- unencryptedLogs: ${JSON.stringify(this.unencryptedLogs.toJSON())}
- contractClassLogs: ${JSON.stringify(this.contractClassLogs.toJSON())}
+ noteEncryptedLogs: ${jsonStringify(this.noteEncryptedLogs)},
+ encryptedLogs: ${jsonStringify(this.encryptedLogs)},
+ unencryptedLogs: ${jsonStringify(this.unencryptedLogs)}
+ contractClassLogs: ${jsonStringify(this.contractClassLogs)}
}`;
}
@@ -303,7 +338,7 @@ export class TxEffect {
* @returns An instance of TxEffect.
*/
static fromString(str: string) {
- return TxEffect.fromBuffer(Buffer.from(str, 'hex'));
+ return TxEffect.fromBuffer(hexToBuffer(str));
}
get txHash(): TxHash {
diff --git a/yarn-project/circuit-types/src/tx_execution_request.test.ts b/yarn-project/circuit-types/src/tx_execution_request.test.ts
index 2cb04307dfa..d1de9f1c4db 100644
--- a/yarn-project/circuit-types/src/tx_execution_request.test.ts
+++ b/yarn-project/circuit-types/src/tx_execution_request.test.ts
@@ -1,6 +1,5 @@
-import { jsonStringify } from '@aztec/foundation/json-rpc';
+import { jsonParseWithSchema, jsonStringify } from '@aztec/foundation/json-rpc';
-import { jsonParseWithSchema } from '../../foundation/src/json-rpc/convert.js';
import { TxExecutionRequest } from './tx_execution_request.js';
describe('TxExecutionRequest', () => {
diff --git a/yarn-project/circuit-types/src/tx_execution_request.ts b/yarn-project/circuit-types/src/tx_execution_request.ts
index 9588de8c160..2a99636da2e 100644
--- a/yarn-project/circuit-types/src/tx_execution_request.ts
+++ b/yarn-project/circuit-types/src/tx_execution_request.ts
@@ -1,6 +1,7 @@
import { AztecAddress, Fr, FunctionData, FunctionSelector, TxContext, TxRequest, Vector } from '@aztec/circuits.js';
import { schemas } from '@aztec/foundation/schemas';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { type FieldsOf } from '@aztec/foundation/types';
import { z } from 'zod';
@@ -101,7 +102,7 @@ export class TxExecutionRequest {
* @returns The string.
*/
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
/**
@@ -127,7 +128,7 @@ export class TxExecutionRequest {
* @returns The deserialized TxRequest object.
*/
static fromString(str: string): TxExecutionRequest {
- return TxExecutionRequest.fromBuffer(Buffer.from(str, 'hex'));
+ return TxExecutionRequest.fromBuffer(hexToBuffer(str));
}
static random() {
diff --git a/yarn-project/circuits.js/src/contract/interfaces/contract_class.ts b/yarn-project/circuits.js/src/contract/interfaces/contract_class.ts
index 82d0a4960a2..002c3ac4f75 100644
--- a/yarn-project/circuits.js/src/contract/interfaces/contract_class.ts
+++ b/yarn-project/circuits.js/src/contract/interfaces/contract_class.ts
@@ -45,7 +45,7 @@ export interface ExecutablePrivateFunction extends PrivateFunction {
}
const ExecutablePrivateFunctionSchema = PrivateFunctionSchema.and(
- z.object({ bytecode: schemas.BufferB64 }),
+ z.object({ bytecode: schemas.Buffer }),
) satisfies ZodFor;
/** Public function definition within a contract class. */
@@ -58,7 +58,7 @@ export interface PublicFunction {
export const PublicFunctionSchema = z.object({
selector: schemas.FunctionSelector,
- bytecode: schemas.BufferB64,
+ bytecode: schemas.Buffer,
}) satisfies ZodFor;
/** Unconstrained function definition. */
@@ -72,7 +72,7 @@ export interface UnconstrainedFunction {
const UnconstrainedFunctionSchema = z.object({
/** lala */
selector: schemas.FunctionSelector,
- bytecode: schemas.BufferB64,
+ bytecode: schemas.Buffer,
}) satisfies ZodFor;
/** Sibling paths and sibling commitments for proving membership of a private function within a contract class. */
@@ -124,7 +124,7 @@ export const ContractClassSchema = z.object({
artifactHash: schemas.Fr,
privateFunctions: z.array(PrivateFunctionSchema),
publicFunctions: z.array(PublicFunctionSchema),
- packedBytecode: schemas.BufferB64,
+ packedBytecode: schemas.Buffer,
}) satisfies ZodFor;
/** Commitments to fields of a contract class. */
diff --git a/yarn-project/circuits.js/src/structs/__snapshots__/revert_code.test.ts.snap b/yarn-project/circuits.js/src/structs/__snapshots__/revert_code.test.ts.snap
index a4fdeb08c29..5cc25a3728b 100644
--- a/yarn-project/circuits.js/src/structs/__snapshots__/revert_code.test.ts.snap
+++ b/yarn-project/circuits.js/src/structs/__snapshots__/revert_code.test.ts.snap
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`revert_code should serialize properly 1`] = `
+exports[`revert_code should serialize RevertCode<0> properly 1`] = `
{
"data": [
0,
@@ -40,7 +40,7 @@ exports[`revert_code should serialize properly 1`] = `
}
`;
-exports[`revert_code should serialize properly 2`] = `
+exports[`revert_code should serialize RevertCode<0> properly 2`] = `
{
"data": [
0,
@@ -49,14 +49,9 @@ exports[`revert_code should serialize properly 2`] = `
}
`;
-exports[`revert_code should serialize properly 3`] = `
-{
- "type": "Fr",
- "value": "0x0000000000000000000000000000000000000000000000000000000000000000",
-}
-`;
+exports[`revert_code should serialize RevertCode<0> properly 3`] = `"0x0000000000000000000000000000000000000000000000000000000000000000"`;
-exports[`revert_code should serialize properly 4`] = `
+exports[`revert_code should serialize RevertCode<1> properly 1`] = `
{
"data": [
0,
@@ -96,7 +91,7 @@ exports[`revert_code should serialize properly 4`] = `
}
`;
-exports[`revert_code should serialize properly 5`] = `
+exports[`revert_code should serialize RevertCode<1> properly 2`] = `
{
"data": [
1,
@@ -105,14 +100,9 @@ exports[`revert_code should serialize properly 5`] = `
}
`;
-exports[`revert_code should serialize properly 6`] = `
-{
- "type": "Fr",
- "value": "0x0000000000000000000000000000000000000000000000000000000000000001",
-}
-`;
+exports[`revert_code should serialize RevertCode<1> properly 3`] = `"0x0000000000000000000000000000000000000000000000000000000000000001"`;
-exports[`revert_code should serialize properly 7`] = `
+exports[`revert_code should serialize RevertCode<2> properly 1`] = `
{
"data": [
0,
@@ -152,7 +142,7 @@ exports[`revert_code should serialize properly 7`] = `
}
`;
-exports[`revert_code should serialize properly 8`] = `
+exports[`revert_code should serialize RevertCode<2> properly 2`] = `
{
"data": [
2,
@@ -161,14 +151,9 @@ exports[`revert_code should serialize properly 8`] = `
}
`;
-exports[`revert_code should serialize properly 9`] = `
-{
- "type": "Fr",
- "value": "0x0000000000000000000000000000000000000000000000000000000000000002",
-}
-`;
+exports[`revert_code should serialize RevertCode<2> properly 3`] = `"0x0000000000000000000000000000000000000000000000000000000000000002"`;
-exports[`revert_code should serialize properly 10`] = `
+exports[`revert_code should serialize RevertCode<3> properly 1`] = `
{
"data": [
0,
@@ -208,7 +193,7 @@ exports[`revert_code should serialize properly 10`] = `
}
`;
-exports[`revert_code should serialize properly 11`] = `
+exports[`revert_code should serialize RevertCode<3> properly 2`] = `
{
"data": [
3,
@@ -217,9 +202,4 @@ exports[`revert_code should serialize properly 11`] = `
}
`;
-exports[`revert_code should serialize properly 12`] = `
-{
- "type": "Fr",
- "value": "0x0000000000000000000000000000000000000000000000000000000000000003",
-}
-`;
+exports[`revert_code should serialize RevertCode<3> properly 3`] = `"0x0000000000000000000000000000000000000000000000000000000000000003"`;
diff --git a/yarn-project/circuits.js/src/structs/avm/avm.ts b/yarn-project/circuits.js/src/structs/avm/avm.ts
index b4020f36511..30c37a7b132 100644
--- a/yarn-project/circuits.js/src/structs/avm/avm.ts
+++ b/yarn-project/circuits.js/src/structs/avm/avm.ts
@@ -1,8 +1,9 @@
import { PublicDataTreeLeafPreimage } from '@aztec/circuits.js';
import { AztecAddress } from '@aztec/foundation/aztec-address';
import { Fr } from '@aztec/foundation/fields';
-import { hexSchemaFor } from '@aztec/foundation/schemas';
+import { bufferSchemaFor } from '@aztec/foundation/schemas';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { type FieldsOf } from '@aztec/foundation/types';
import { type ContractClassIdPreimage } from '../../contract/contract_class_id.js';
@@ -34,7 +35,7 @@ export class AvmEnqueuedCallHint {
* @returns The instance serialized to a hex string.
*/
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
/**
@@ -79,7 +80,7 @@ export class AvmEnqueuedCallHint {
* @returns The deserialized instance.
*/
static fromString(str: string): AvmEnqueuedCallHint {
- return AvmEnqueuedCallHint.fromBuffer(Buffer.from(str, 'hex'));
+ return AvmEnqueuedCallHint.fromBuffer(hexToBuffer(str));
}
}
@@ -100,7 +101,7 @@ export class AvmKeyValueHint {
* @returns The instance serialized to a hex string.
*/
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
/**
@@ -145,7 +146,7 @@ export class AvmKeyValueHint {
* @returns The deserialized instance.
*/
static fromString(str: string): AvmKeyValueHint {
- return AvmKeyValueHint.fromBuffer(Buffer.from(str, 'hex'));
+ return AvmKeyValueHint.fromBuffer(hexToBuffer(str));
}
}
@@ -182,7 +183,7 @@ export class AvmExternalCallHint {
* @returns The instance serialized to a hex string.
*/
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
/**
@@ -245,7 +246,7 @@ export class AvmExternalCallHint {
* @returns The deserialized instance.
*/
static fromString(str: string): AvmExternalCallHint {
- return AvmExternalCallHint.fromBuffer(Buffer.from(str, 'hex'));
+ return AvmExternalCallHint.fromBuffer(hexToBuffer(str));
}
}
@@ -272,7 +273,7 @@ export class AvmContractInstanceHint {
* @returns The instance serialized to a hex string.
*/
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
/**
@@ -341,7 +342,7 @@ export class AvmContractInstanceHint {
* @returns The deserialized instance.
*/
static fromString(str: string): AvmContractInstanceHint {
- return AvmContractInstanceHint.fromBuffer(Buffer.from(str, 'hex'));
+ return AvmContractInstanceHint.fromBuffer(hexToBuffer(str));
}
}
@@ -369,7 +370,7 @@ export class AvmContractBytecodeHints {
* @returns The instance serialized to a hex string.
*/
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
/**
@@ -434,7 +435,7 @@ export class AvmContractBytecodeHints {
* @returns The deserialized instance.
*/
static fromString(str: string): AvmContractBytecodeHints {
- return AvmContractBytecodeHints.fromBuffer(Buffer.from(str, 'hex'));
+ return AvmContractBytecodeHints.fromBuffer(hexToBuffer(str));
}
}
@@ -914,7 +915,7 @@ export class AvmExecutionHints {
* @returns The instance serialized to a hex string.
*/
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
/**
@@ -1026,7 +1027,7 @@ export class AvmExecutionHints {
* @returns The deserialized instance.
*/
static fromString(str: string): AvmCircuitInputs {
- return AvmCircuitInputs.fromBuffer(Buffer.from(str, 'hex'));
+ return AvmCircuitInputs.fromBuffer(hexToBuffer(str));
}
}
@@ -1061,7 +1062,7 @@ export class AvmCircuitInputs {
* @returns The instance serialized to a hex string.
*/
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
static empty(): AvmCircuitInputs {
@@ -1114,16 +1115,16 @@ export class AvmCircuitInputs {
* @returns The deserialized instance.
*/
static fromString(str: string): AvmCircuitInputs {
- return AvmCircuitInputs.fromBuffer(Buffer.from(str, 'hex'));
+ return AvmCircuitInputs.fromBuffer(hexToBuffer(str));
}
- /** Returns a hex representation for JSON serialization. */
+ /** Returns a buffer representation for JSON serialization. */
toJSON() {
- return this.toString();
+ return this.toBuffer();
}
/** Creates an instance from a hex string. */
static get schema() {
- return hexSchemaFor(AvmCircuitInputs);
+ return bufferSchemaFor(AvmCircuitInputs);
}
}
diff --git a/yarn-project/circuits.js/src/structs/avm/avm_accumulated_data.ts b/yarn-project/circuits.js/src/structs/avm/avm_accumulated_data.ts
index 2e01efc6ee2..c68d93b13e4 100644
--- a/yarn-project/circuits.js/src/structs/avm/avm_accumulated_data.ts
+++ b/yarn-project/circuits.js/src/structs/avm/avm_accumulated_data.ts
@@ -2,6 +2,7 @@ import { makeTuple } from '@aztec/foundation/array';
import { arraySerializedSizeOfNonEmpty } from '@aztec/foundation/collection';
import { Fr } from '@aztec/foundation/fields';
import { BufferReader, FieldReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { inspect } from 'util';
@@ -83,11 +84,11 @@ export class AvmAccumulatedData {
}
static fromString(str: string) {
- return this.fromBuffer(Buffer.from(str, 'hex'));
+ return this.fromBuffer(hexToBuffer(str));
}
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
static empty() {
diff --git a/yarn-project/circuits.js/src/structs/avm/avm_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/avm/avm_circuit_public_inputs.ts
index 0ff41750b69..8877b4b8003 100644
--- a/yarn-project/circuits.js/src/structs/avm/avm_circuit_public_inputs.ts
+++ b/yarn-project/circuits.js/src/structs/avm/avm_circuit_public_inputs.ts
@@ -1,6 +1,7 @@
import { makeTuple } from '@aztec/foundation/array';
import { Fr } from '@aztec/foundation/fields';
import { BufferReader, FieldReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { inspect } from 'util';
@@ -80,11 +81,11 @@ export class AvmCircuitPublicInputs {
}
static fromString(str: string) {
- return AvmCircuitPublicInputs.fromBuffer(Buffer.from(str, 'hex'));
+ return AvmCircuitPublicInputs.fromBuffer(hexToBuffer(str));
}
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
static fromFields(fields: Fr[] | FieldReader) {
diff --git a/yarn-project/circuits.js/src/structs/client_ivc_proof.ts b/yarn-project/circuits.js/src/structs/client_ivc_proof.ts
index 737870e5080..a35b8f6c84f 100644
--- a/yarn-project/circuits.js/src/structs/client_ivc_proof.ts
+++ b/yarn-project/circuits.js/src/structs/client_ivc_proof.ts
@@ -1,4 +1,4 @@
-import { hexSchemaFor } from '@aztec/foundation/schemas';
+import { bufferSchemaFor } from '@aztec/foundation/schemas';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
import * as fs from 'fs/promises';
@@ -67,12 +67,11 @@ export class ClientIvcProof {
}
static get schema() {
- // TODO(palla/schemas): Consider using a b64 schema instead
- return hexSchemaFor(ClientIvcProof);
+ return bufferSchemaFor(ClientIvcProof);
}
toJSON() {
- return '0x' + this.toBuffer().toString('hex');
+ return this.toBuffer();
}
static fromBuffer(buffer: Buffer | BufferReader): ClientIvcProof {
diff --git a/yarn-project/circuits.js/src/structs/complete_address.ts b/yarn-project/circuits.js/src/structs/complete_address.ts
index 04d083ae50c..5fbd1132e40 100644
--- a/yarn-project/circuits.js/src/structs/complete_address.ts
+++ b/yarn-project/circuits.js/src/structs/complete_address.ts
@@ -2,6 +2,7 @@ import { AztecAddress } from '@aztec/foundation/aztec-address';
import { Fr } from '@aztec/foundation/fields';
import { hexSchemaFor } from '@aztec/foundation/schemas';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex } from '@aztec/foundation/string';
import { computePartialAddress } from '../contract/contract_address.js';
import { computeAddress, computePreaddress, deriveKeys } from '../keys/index.js';
@@ -141,6 +142,6 @@ export class CompleteAddress {
* @returns A hexadecimal string representation of the CompleteAddress.
*/
toString(): string {
- return `0x${this.toBuffer().toString('hex')}`;
+ return bufferToHex(this.toBuffer());
}
}
diff --git a/yarn-project/circuits.js/src/structs/content_commitment.ts b/yarn-project/circuits.js/src/structs/content_commitment.ts
index 578a6831ff5..8e2e9680ba2 100644
--- a/yarn-project/circuits.js/src/structs/content_commitment.ts
+++ b/yarn-project/circuits.js/src/structs/content_commitment.ts
@@ -1,6 +1,7 @@
import { Fr } from '@aztec/foundation/fields';
import { schemas } from '@aztec/foundation/schemas';
import { BufferReader, FieldReader, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex } from '@aztec/foundation/string';
import { z } from 'zod';
@@ -34,24 +35,15 @@ export class ContentCommitment {
return z
.object({
numTxs: schemas.Fr,
- txsEffectsHash: schemas.BufferHex,
- inHash: schemas.BufferHex,
- outHash: schemas.BufferHex,
+ txsEffectsHash: schemas.Buffer,
+ inHash: schemas.Buffer,
+ outHash: schemas.Buffer,
})
.transform(
({ numTxs, txsEffectsHash, inHash, outHash }) => new ContentCommitment(numTxs, txsEffectsHash, inHash, outHash),
);
}
- toJSON() {
- return {
- numTxs: this.numTxs,
- txsEffectsHash: this.txsEffectsHash.toString('hex'),
- inHash: this.inHash.toString('hex'),
- outHash: this.outHash.toString('hex'),
- };
- }
-
getSize() {
return this.toBuffer().length;
}
@@ -113,7 +105,7 @@ export class ContentCommitment {
}
public toString(): string {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
static fromString(str: string): ContentCommitment {
diff --git a/yarn-project/circuits.js/src/structs/function_data.ts b/yarn-project/circuits.js/src/structs/function_data.ts
index 02f58a2deaa..afc63a96d21 100644
--- a/yarn-project/circuits.js/src/structs/function_data.ts
+++ b/yarn-project/circuits.js/src/structs/function_data.ts
@@ -1,7 +1,10 @@
import { type FunctionAbi, FunctionSelector, FunctionType } from '@aztec/foundation/abi';
import { Fr } from '@aztec/foundation/fields';
+import { schemas } from '@aztec/foundation/schemas';
import { BufferReader, FieldReader, serializeToBuffer } from '@aztec/foundation/serialize';
+import { z } from 'zod';
+
import { FUNCTION_DATA_LENGTH } from '../constants.gen.js';
import { type ContractFunctionDao } from '../types/contract_function_dao.js';
@@ -21,6 +24,15 @@ export class FunctionData {
);
}
+ static get schema() {
+ return z
+ .object({
+ selector: schemas.FunctionSelector,
+ isPrivate: z.boolean(),
+ })
+ .transform(({ selector, isPrivate }) => new FunctionData(selector, isPrivate));
+ }
+
/**
* Serialize this as a buffer.
* @returns The buffer.
@@ -88,15 +100,4 @@ export class FunctionData {
return new FunctionData(selector, isPrivate);
}
-
- public toJSON() {
- return {
- selector: this.selector.toString(),
- isPrivate: this.isPrivate,
- };
- }
-
- public static fromJSON(json: any) {
- return new FunctionData(FunctionSelector.fromString(json.selector), json.isPrivate);
- }
}
diff --git a/yarn-project/circuits.js/src/structs/gas.ts b/yarn-project/circuits.js/src/structs/gas.ts
index 4dc6f24f087..7952b2cbbbd 100644
--- a/yarn-project/circuits.js/src/structs/gas.ts
+++ b/yarn-project/circuits.js/src/structs/gas.ts
@@ -93,12 +93,4 @@ export class Gas {
const reader = FieldReader.asReader(fields);
return new Gas(reader.readU32(), reader.readU32());
}
-
- toJSON() {
- return { daGas: this.daGas, l2Gas: this.l2Gas };
- }
-
- static fromJSON(json: any) {
- return new Gas(json.daGas, json.l2Gas);
- }
}
diff --git a/yarn-project/circuits.js/src/structs/gas_fees.ts b/yarn-project/circuits.js/src/structs/gas_fees.ts
index 6cab097c0ce..dcaabb12da8 100644
--- a/yarn-project/circuits.js/src/structs/gas_fees.ts
+++ b/yarn-project/circuits.js/src/structs/gas_fees.ts
@@ -83,17 +83,6 @@ export class GasFees {
return serializeToFields(this.feePerDaGas, this.feePerL2Gas);
}
- static fromJSON(obj: any) {
- return new GasFees(Fr.fromString(obj.feePerDaGas), Fr.fromString(obj.feePerL2Gas));
- }
-
- toJSON() {
- return {
- feePerDaGas: this.feePerDaGas.toString(),
- feePerL2Gas: this.feePerL2Gas.toString(),
- };
- }
-
[inspect.custom]() {
return `GasFees { feePerDaGas=${this.feePerDaGas} feePerL2Gas=${this.feePerL2Gas} }`;
}
diff --git a/yarn-project/circuits.js/src/structs/global_variables.ts b/yarn-project/circuits.js/src/structs/global_variables.ts
index f49badfe8ff..914dc7b5fb6 100644
--- a/yarn-project/circuits.js/src/structs/global_variables.ts
+++ b/yarn-project/circuits.js/src/structs/global_variables.ts
@@ -1,6 +1,7 @@
import { AztecAddress } from '@aztec/foundation/aztec-address';
import { EthAddress } from '@aztec/foundation/eth-address';
import { Fr } from '@aztec/foundation/fields';
+import { jsonStringify } from '@aztec/foundation/json-rpc';
import { schemas } from '@aztec/foundation/schemas';
import { BufferReader, FieldReader, serializeToBuffer, serializeToFields } from '@aztec/foundation/serialize';
import { type FieldsOf } from '@aztec/foundation/types';
@@ -84,19 +85,6 @@ export class GlobalVariables {
);
}
- static fromJSON(obj: any): GlobalVariables {
- return new GlobalVariables(
- Fr.fromString(obj.chainId),
- Fr.fromString(obj.version),
- Fr.fromString(obj.blockNumber),
- Fr.fromString(obj.slotNumber),
- Fr.fromString(obj.timestamp),
- EthAddress.fromString(obj.coinbase),
- AztecAddress.fromString(obj.feeRecipient),
- GasFees.fromJSON(obj.gasFees),
- );
- }
-
static fromFields(fields: Fr[] | FieldReader): GlobalVariables {
const reader = FieldReader.asReader(fields);
@@ -140,19 +128,6 @@ export class GlobalVariables {
return fields;
}
- toJSON() {
- return {
- chainId: this.chainId.toString(),
- version: this.version.toString(),
- blockNumber: this.blockNumber.toString(),
- slotNumber: this.slotNumber.toString(),
- timestamp: this.timestamp.toString(),
- coinbase: this.coinbase.toString(),
- feeRecipient: this.feeRecipient.toString(),
- gasFees: this.gasFees.toJSON(),
- };
- }
-
/**
* A trimmed version of the JSON representation of the global variables,
* tailored for human consumption.
@@ -163,7 +138,7 @@ export class GlobalVariables {
slotNumber: this.slotNumber.toNumber(),
timestamp: this.timestamp.toString(),
coinbase: this.coinbase.toString(),
- gasFees: this.gasFees.toJSON(),
+ gasFees: jsonStringify(this.gasFees),
};
}
diff --git a/yarn-project/circuits.js/src/structs/header.ts b/yarn-project/circuits.js/src/structs/header.ts
index f31f85a2ef9..654d202eb51 100644
--- a/yarn-project/circuits.js/src/structs/header.ts
+++ b/yarn-project/circuits.js/src/structs/header.ts
@@ -2,6 +2,7 @@ import { poseidon2HashWithSeparator } from '@aztec/foundation/crypto';
import { Fr } from '@aztec/foundation/fields';
import { schemas } from '@aztec/foundation/schemas';
import { BufferReader, FieldReader, serializeToBuffer, serializeToFields } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { type FieldsOf } from '@aztec/foundation/types';
import { inspect } from 'util';
@@ -40,16 +41,6 @@ export class Header {
.transform(Header.from);
}
- toJSON() {
- return {
- lastArchive: this.lastArchive,
- contentCommitment: this.contentCommitment,
- state: this.state,
- globalVariables: this.globalVariables,
- totalFees: this.totalFees,
- };
- }
-
static getFields(fields: FieldsOf) {
// Note: The order here must match the order in the HeaderLib solidity library.
return [
@@ -139,13 +130,12 @@ export class Header {
* Serializes this instance into a string.
* @returns Encoded string.
*/
- public toString(): string {
- return this.toBuffer().toString('hex');
+ public toString() {
+ return bufferToHex(this.toBuffer());
}
static fromString(str: string): Header {
- const buffer = Buffer.from(str.replace(/^0x/i, ''), 'hex');
- return Header.fromBuffer(buffer);
+ return Header.fromBuffer(hexToBuffer(str));
}
hash(): Fr {
diff --git a/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts b/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts
index 16ba5e3b7b7..b245c70f7b6 100644
--- a/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts
+++ b/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts
@@ -1,8 +1,9 @@
import { type FieldsOf, makeTuple } from '@aztec/foundation/array';
import { arraySerializedSizeOfNonEmpty } from '@aztec/foundation/collection';
import { Fr } from '@aztec/foundation/fields';
-import { hexSchemaFor } from '@aztec/foundation/schemas';
+import { bufferSchemaFor } from '@aztec/foundation/schemas';
import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { inspect } from 'util';
@@ -116,11 +117,11 @@ export class CombinedAccumulatedData {
}
static get schema() {
- return hexSchemaFor(CombinedAccumulatedData);
+ return bufferSchemaFor(CombinedAccumulatedData);
}
toJSON() {
- return this.toString();
+ return this.toBuffer();
}
toBuffer() {
@@ -128,7 +129,7 @@ export class CombinedAccumulatedData {
}
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
/**
@@ -160,7 +161,7 @@ export class CombinedAccumulatedData {
* @returns Deserialized object.
*/
static fromString(str: string) {
- return CombinedAccumulatedData.fromBuffer(Buffer.from(str, 'hex'));
+ return CombinedAccumulatedData.fromBuffer(hexToBuffer(str));
}
static empty() {
diff --git a/yarn-project/circuits.js/src/structs/kernel/kernel_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/kernel_circuit_public_inputs.ts
index 2ec58bdd269..e5abfe011f1 100644
--- a/yarn-project/circuits.js/src/structs/kernel/kernel_circuit_public_inputs.ts
+++ b/yarn-project/circuits.js/src/structs/kernel/kernel_circuit_public_inputs.ts
@@ -1,6 +1,7 @@
import { AztecAddress } from '@aztec/foundation/aztec-address';
-import { hexSchemaFor } from '@aztec/foundation/schemas';
+import { bufferSchemaFor } from '@aztec/foundation/schemas';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { Gas } from '../gas.js';
import { PartialStateReference } from '../partial_state_reference.js';
@@ -89,20 +90,20 @@ export class KernelCircuitPublicInputs {
}
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
static fromString(str: string) {
- return KernelCircuitPublicInputs.fromBuffer(Buffer.from(str, 'hex'));
+ return KernelCircuitPublicInputs.fromBuffer(hexToBuffer(str));
}
/** Returns a hex representation for JSON serialization. */
toJSON() {
- return this.toString();
+ return this.toBuffer();
}
/** Creates an instance from a hex string. */
static get schema() {
- return hexSchemaFor(KernelCircuitPublicInputs);
+ return bufferSchemaFor(KernelCircuitPublicInputs);
}
}
diff --git a/yarn-project/circuits.js/src/structs/kernel/private_accumulated_data.ts b/yarn-project/circuits.js/src/structs/kernel/private_accumulated_data.ts
index 86b7a03ac7f..a314fdde586 100644
--- a/yarn-project/circuits.js/src/structs/kernel/private_accumulated_data.ts
+++ b/yarn-project/circuits.js/src/structs/kernel/private_accumulated_data.ts
@@ -1,5 +1,6 @@
import { makeTuple } from '@aztec/foundation/array';
import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import {
MAX_CONTRACT_CLASS_LOGS_PER_TX,
@@ -75,7 +76,7 @@ export class PrivateAccumulatedData {
}
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
/**
@@ -103,7 +104,7 @@ export class PrivateAccumulatedData {
* @returns Deserialized object.
*/
static fromString(str: string) {
- return PrivateAccumulatedData.fromBuffer(Buffer.from(str, 'hex'));
+ return PrivateAccumulatedData.fromBuffer(hexToBuffer(str));
}
static empty() {
diff --git a/yarn-project/circuits.js/src/structs/kernel/private_kernel_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/private_kernel_circuit_public_inputs.ts
index 1db065b1464..1839ce2c98d 100644
--- a/yarn-project/circuits.js/src/structs/kernel/private_kernel_circuit_public_inputs.ts
+++ b/yarn-project/circuits.js/src/structs/kernel/private_kernel_circuit_public_inputs.ts
@@ -1,6 +1,6 @@
import { AztecAddress } from '@aztec/foundation/aztec-address';
import { Fr } from '@aztec/foundation/fields';
-import { hexSchemaFor } from '@aztec/foundation/schemas';
+import { bufferSchemaFor } from '@aztec/foundation/schemas';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
import { PrivateValidationRequests } from '../private_validation_requests.js';
@@ -40,11 +40,11 @@ export class PrivateKernelCircuitPublicInputs {
) {}
static get schema() {
- return hexSchemaFor(PrivateKernelCircuitPublicInputs);
+ return bufferSchemaFor(PrivateKernelCircuitPublicInputs);
}
toJSON() {
- return '0x' + this.toBuffer().toString('hex');
+ return this.toBuffer();
}
toBuffer() {
diff --git a/yarn-project/circuits.js/src/structs/kernel/private_kernel_empty_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/private_kernel_empty_inputs.ts
index 0a97d999581..9fe7957baa0 100644
--- a/yarn-project/circuits.js/src/structs/kernel/private_kernel_empty_inputs.ts
+++ b/yarn-project/circuits.js/src/structs/kernel/private_kernel_empty_inputs.ts
@@ -1,6 +1,7 @@
import { Fr } from '@aztec/foundation/fields';
-import { hexSchemaFor } from '@aztec/foundation/schemas';
+import { bufferSchemaFor } from '@aztec/foundation/schemas';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { type FieldsOf } from '@aztec/foundation/types';
import { RECURSIVE_PROOF_LENGTH } from '../../constants.gen.js';
@@ -22,7 +23,7 @@ export class PrivateKernelEmptyInputData {
}
toString(): string {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
static fromBuffer(buf: Buffer) {
@@ -37,7 +38,7 @@ export class PrivateKernelEmptyInputData {
}
static fromString(str: string): PrivateKernelEmptyInputData {
- return PrivateKernelEmptyInputData.fromBuffer(Buffer.from(str, 'hex'));
+ return PrivateKernelEmptyInputData.fromBuffer(hexToBuffer(str));
}
static from(fields: FieldsOf) {
@@ -50,14 +51,14 @@ export class PrivateKernelEmptyInputData {
);
}
- /** Returns a hex representation for JSON serialization. */
+ /** Returns a buffer representation for JSON serialization. */
toJSON() {
- return this.toString();
+ return this.toBuffer();
}
/** Creates an instance from a hex string. */
static get schema() {
- return hexSchemaFor(PrivateKernelEmptyInputData);
+ return bufferSchemaFor(PrivateKernelEmptyInputData);
}
}
diff --git a/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_public_inputs.ts
index 7ce5ae26c0d..d21a7590db9 100644
--- a/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_public_inputs.ts
+++ b/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_public_inputs.ts
@@ -1,6 +1,6 @@
import { AztecAddress } from '@aztec/foundation/aztec-address';
import { Fr } from '@aztec/foundation/fields';
-import { hexSchemaFor } from '@aztec/foundation/schemas';
+import { bufferSchemaFor } from '@aztec/foundation/schemas';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
import { countAccumulatedItems, mergeAccumulatedData } from '../../utils/index.js';
@@ -131,11 +131,11 @@ export class PrivateKernelTailCircuitPublicInputs {
}
static get schema() {
- return hexSchemaFor(PrivateKernelTailCircuitPublicInputs);
+ return bufferSchemaFor(PrivateKernelTailCircuitPublicInputs);
}
toJSON() {
- return '0x' + this.toBuffer().toString('hex');
+ return this.toBuffer();
}
getSize() {
diff --git a/yarn-project/circuits.js/src/structs/kernel/private_to_public_kernel_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/private_to_public_kernel_circuit_public_inputs.ts
index 7a93e0cee96..ed837be8084 100644
--- a/yarn-project/circuits.js/src/structs/kernel/private_to_public_kernel_circuit_public_inputs.ts
+++ b/yarn-project/circuits.js/src/structs/kernel/private_to_public_kernel_circuit_public_inputs.ts
@@ -1,5 +1,6 @@
import { AztecAddress } from '@aztec/foundation/aztec-address';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { Gas } from '../gas.js';
import { PublicCallRequest } from '../public_call_request.js';
@@ -56,10 +57,10 @@ export class PrivateToPublicKernelCircuitPublicInputs {
}
static fromString(str: string) {
- return PrivateToPublicKernelCircuitPublicInputs.fromBuffer(Buffer.from(str, 'hex'));
+ return PrivateToPublicKernelCircuitPublicInputs.fromBuffer(hexToBuffer(str));
}
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
}
diff --git a/yarn-project/circuits.js/src/structs/parity/base_parity_inputs.ts b/yarn-project/circuits.js/src/structs/parity/base_parity_inputs.ts
index 44a6804c840..a02b44025a3 100644
--- a/yarn-project/circuits.js/src/structs/parity/base_parity_inputs.ts
+++ b/yarn-project/circuits.js/src/structs/parity/base_parity_inputs.ts
@@ -1,6 +1,7 @@
import { Fr } from '@aztec/foundation/fields';
-import { hexSchemaFor } from '@aztec/foundation/schemas';
+import { bufferSchemaFor } from '@aztec/foundation/schemas';
import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { type NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, NUM_MSGS_PER_BASE_PARITY } from '../../constants.gen.js';
@@ -30,7 +31,7 @@ export class BaseParityInputs {
/** Serializes the inputs to a hex string. */
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
/**
@@ -48,16 +49,16 @@ export class BaseParityInputs {
* @returns - The deserialized inputs.
*/
static fromString(str: string) {
- return BaseParityInputs.fromBuffer(Buffer.from(str, 'hex'));
+ return BaseParityInputs.fromBuffer(hexToBuffer(str));
}
- /** Returns a hex representation for JSON serialization. */
+ /** Returns a buffer representation for JSON serialization. */
toJSON() {
- return this.toString();
+ return this.toBuffer();
}
/** Creates an instance from a hex string. */
static get schema() {
- return hexSchemaFor(BaseParityInputs);
+ return bufferSchemaFor(BaseParityInputs);
}
}
diff --git a/yarn-project/circuits.js/src/structs/parity/parity_public_inputs.ts b/yarn-project/circuits.js/src/structs/parity/parity_public_inputs.ts
index d0cd63e2565..1f2f3551c02 100644
--- a/yarn-project/circuits.js/src/structs/parity/parity_public_inputs.ts
+++ b/yarn-project/circuits.js/src/structs/parity/parity_public_inputs.ts
@@ -1,6 +1,7 @@
import { Fr } from '@aztec/foundation/fields';
-import { hexSchemaFor } from '@aztec/foundation/schemas';
+import { bufferSchemaFor } from '@aztec/foundation/schemas';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { type FieldsOf } from '@aztec/foundation/types';
export class ParityPublicInputs {
@@ -30,12 +31,12 @@ export class ParityPublicInputs {
* @returns The inputs serialized to a hex string.
*/
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
- /** Returns a hex representation for JSON serialization. */
+ /** Returns a representation for JSON serialization. */
toJSON() {
- return this.toString();
+ return this.toBuffer();
}
/**
@@ -72,10 +73,10 @@ export class ParityPublicInputs {
* @returns A new ParityPublicInputs instance.
*/
static fromString(str: string) {
- return ParityPublicInputs.fromBuffer(Buffer.from(str, 'hex'));
+ return ParityPublicInputs.fromBuffer(hexToBuffer(str));
}
static get schema() {
- return hexSchemaFor(ParityPublicInputs);
+ return bufferSchemaFor(ParityPublicInputs);
}
}
diff --git a/yarn-project/circuits.js/src/structs/parity/root_parity_input.ts b/yarn-project/circuits.js/src/structs/parity/root_parity_input.ts
index aa26e28386e..e9b159b4387 100644
--- a/yarn-project/circuits.js/src/structs/parity/root_parity_input.ts
+++ b/yarn-project/circuits.js/src/structs/parity/root_parity_input.ts
@@ -1,6 +1,7 @@
import { Fr } from '@aztec/foundation/fields';
import { schemas } from '@aztec/foundation/schemas';
import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { type FieldsOf } from '@aztec/foundation/types';
import { VK_TREE_HEIGHT } from '../../constants.gen.js';
@@ -25,7 +26,7 @@ export class RootParityInput {
}
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
static from(
@@ -55,16 +56,16 @@ export class RootParityInput {
str: string,
expectedSize?: PROOF_LENGTH,
): RootParityInput {
- return RootParityInput.fromBuffer(Buffer.from(str, 'hex'), expectedSize);
+ return RootParityInput.fromBuffer(hexToBuffer(str), expectedSize);
}
/** Returns a hex representation for JSON serialization. */
toJSON() {
- return this.toString();
+ return this.toBuffer();
}
/** Creates an instance from a hex string with expected size. */
static schemaFor(expectedSize?: N) {
- return schemas.HexString.transform(str => RootParityInput.fromString(str, expectedSize));
+ return schemas.Buffer.transform(buf => RootParityInput.fromBuffer(buf, expectedSize));
}
}
diff --git a/yarn-project/circuits.js/src/structs/parity/root_parity_inputs.ts b/yarn-project/circuits.js/src/structs/parity/root_parity_inputs.ts
index aa74c1092f2..2b09078c755 100644
--- a/yarn-project/circuits.js/src/structs/parity/root_parity_inputs.ts
+++ b/yarn-project/circuits.js/src/structs/parity/root_parity_inputs.ts
@@ -1,5 +1,6 @@
-import { hexSchemaFor } from '@aztec/foundation/schemas';
+import { bufferSchemaFor } from '@aztec/foundation/schemas';
import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { NUM_BASE_PARITY_PER_ROOT_PARITY, RECURSIVE_PROOF_LENGTH } from '../../constants.gen.js';
import { RootParityInput } from './root_parity_input.js';
@@ -26,7 +27,7 @@ export class RootParityInputs {
* @returns The instance serialized to a hex string.
*/
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
/**
@@ -50,16 +51,16 @@ export class RootParityInputs {
* @returns A new RootParityInputs instance.
*/
static fromString(str: string) {
- return RootParityInputs.fromBuffer(Buffer.from(str, 'hex'));
+ return RootParityInputs.fromBuffer(hexToBuffer(str));
}
- /** Returns a hex representation for JSON serialization. */
+ /** Returns a buffer representation for JSON serialization. */
toJSON() {
- return this.toString();
+ return this.toBuffer();
}
/** Creates an instance from a hex string. */
static get schema() {
- return hexSchemaFor(RootParityInputs);
+ return bufferSchemaFor(RootParityInputs);
}
}
diff --git a/yarn-project/circuits.js/src/structs/partial_state_reference.ts b/yarn-project/circuits.js/src/structs/partial_state_reference.ts
index fe484113835..7e212e71262 100644
--- a/yarn-project/circuits.js/src/structs/partial_state_reference.ts
+++ b/yarn-project/circuits.js/src/structs/partial_state_reference.ts
@@ -19,14 +19,6 @@ export class PartialStateReference {
public readonly publicDataTree: AppendOnlyTreeSnapshot,
) {}
- toJSON() {
- return {
- noteHashTree: this.noteHashTree,
- nullifierTree: this.nullifierTree,
- publicDataTree: this.publicDataTree,
- };
- }
-
static get schema() {
return z
.object({
diff --git a/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts
index dfb3fa6d00f..cded605058d 100644
--- a/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts
+++ b/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts
@@ -1,6 +1,6 @@
import { makeTuple } from '@aztec/foundation/array';
import { Fr } from '@aztec/foundation/fields';
-import { hexSchemaFor } from '@aztec/foundation/schemas';
+import { bufferSchemaFor } from '@aztec/foundation/schemas';
import {
BufferReader,
FieldReader,
@@ -323,18 +323,10 @@ export class PrivateCircuitPublicInputs {
}
public toJSON() {
- return this.toBuffer().toString('hex');
- }
-
- public static fromJSON(value: any) {
- return PrivateCircuitPublicInputs.fromBuffer(Buffer.from(value, 'hex'));
- }
-
- public static fromString(str: string) {
- return PrivateCircuitPublicInputs.fromBuffer(Buffer.from(str, 'hex'));
+ return this.toBuffer();
}
static get schema() {
- return hexSchemaFor(PrivateCircuitPublicInputs);
+ return bufferSchemaFor(PrivateCircuitPublicInputs);
}
}
diff --git a/yarn-project/circuits.js/src/structs/private_validation_requests.ts b/yarn-project/circuits.js/src/structs/private_validation_requests.ts
index f026fbfacaf..3b8da4dc030 100644
--- a/yarn-project/circuits.js/src/structs/private_validation_requests.ts
+++ b/yarn-project/circuits.js/src/structs/private_validation_requests.ts
@@ -2,6 +2,7 @@ import { makeTuple } from '@aztec/foundation/array';
import { arraySerializedSizeOfNonEmpty } from '@aztec/foundation/collection';
import { type Fr } from '@aztec/foundation/fields';
import { BufferReader, FieldReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { inspect } from 'util';
@@ -69,7 +70,7 @@ export class PrivateValidationRequests {
}
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
static fromFields(fields: Fr[] | FieldReader) {
@@ -105,7 +106,7 @@ export class PrivateValidationRequests {
* @returns Deserialized object.
*/
static fromString(str: string) {
- return PrivateValidationRequests.fromBuffer(Buffer.from(str, 'hex'));
+ return PrivateValidationRequests.fromBuffer(hexToBuffer(str));
}
static empty() {
diff --git a/yarn-project/circuits.js/src/structs/proof.ts b/yarn-project/circuits.js/src/structs/proof.ts
index 57b57606df4..ec6af85223c 100644
--- a/yarn-project/circuits.js/src/structs/proof.ts
+++ b/yarn-project/circuits.js/src/structs/proof.ts
@@ -1,5 +1,6 @@
import { Fr } from '@aztec/foundation/fields';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { AGGREGATION_OBJECT_LENGTH } from '../constants.gen.js';
@@ -61,7 +62,7 @@ export class Proof {
* @returns The hex string representation of the proof data.
*/
public toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
public withoutPublicInputs(): Buffer {
@@ -89,7 +90,7 @@ export class Proof {
* @returns - A new Proof instance.
*/
static fromString(str: string) {
- return Proof.fromBuffer(Buffer.from(str, 'hex'));
+ return Proof.fromBuffer(hexToBuffer(str));
}
/** Returns whether this proof is actually empty. */
diff --git a/yarn-project/circuits.js/src/structs/public_data_write.ts b/yarn-project/circuits.js/src/structs/public_data_write.ts
index 7f4c2e49ca4..001d14a7878 100644
--- a/yarn-project/circuits.js/src/structs/public_data_write.ts
+++ b/yarn-project/circuits.js/src/structs/public_data_write.ts
@@ -1,7 +1,7 @@
-import { STRING_ENCODING } from '@aztec/circuits.js';
import { Fr } from '@aztec/foundation/fields';
import { schemas } from '@aztec/foundation/schemas';
import { BufferReader, FieldReader, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { type FieldsOf } from '@aztec/foundation/types';
import { z } from 'zod';
@@ -55,11 +55,11 @@ export class PublicDataWrite {
}
static fromString(str: string) {
- return PublicDataWrite.fromBuffer(Buffer.from(str, STRING_ENCODING));
+ return PublicDataWrite.fromBuffer(hexToBuffer(str));
}
toString() {
- return this.toBuffer().toString(STRING_ENCODING);
+ return bufferToHex(this.toBuffer());
}
static empty() {
diff --git a/yarn-project/circuits.js/src/structs/recursive_proof.ts b/yarn-project/circuits.js/src/structs/recursive_proof.ts
index ce5a3b0dcae..d1329ee857a 100644
--- a/yarn-project/circuits.js/src/structs/recursive_proof.ts
+++ b/yarn-project/circuits.js/src/structs/recursive_proof.ts
@@ -2,6 +2,7 @@ import { makeTuple } from '@aztec/foundation/array';
import { Fr } from '@aztec/foundation/fields';
import { schemas } from '@aztec/foundation/schemas';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { Proof, makeEmptyProof } from './proof.js';
@@ -73,7 +74,7 @@ export class RecursiveProof {
* @returns The hex string representation of the proof data.
*/
public toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
/**
@@ -82,17 +83,17 @@ export class RecursiveProof {
* @returns - A new Proof instance.
*/
static fromString(str: string, expectedSize?: N): RecursiveProof {
- return RecursiveProof.fromBuffer(Buffer.from(str, 'hex'), expectedSize);
+ return RecursiveProof.fromBuffer(hexToBuffer(str), expectedSize);
}
- /** Returns a hex representation for JSON serialization. */
+ /** Returns a buffer representation for JSON serialization. */
toJSON() {
- return this.toString();
+ return this.toBuffer();
}
/** Creates an instance from a hex string with expected size. */
static schemaFor(expectedSize?: N) {
- return schemas.HexString.transform(str => RecursiveProof.fromString(str, expectedSize));
+ return schemas.Buffer.transform(b => RecursiveProof.fromBuffer(b, expectedSize));
}
}
diff --git a/yarn-project/circuits.js/src/structs/revert_code.test.ts b/yarn-project/circuits.js/src/structs/revert_code.test.ts
index e2188f7a93a..1fafefb47c4 100644
--- a/yarn-project/circuits.js/src/structs/revert_code.test.ts
+++ b/yarn-project/circuits.js/src/structs/revert_code.test.ts
@@ -1,10 +1,11 @@
import { Fr } from '@aztec/foundation/fields';
+import { jsonStringify } from '@aztec/foundation/json-rpc';
import { RevertCode } from './revert_code.js';
describe('revert_code', () => {
it.each([RevertCode.OK, RevertCode.APP_LOGIC_REVERTED, RevertCode.TEARDOWN_REVERTED, RevertCode.BOTH_REVERTED])(
- 'should serialize properly',
+ 'should serialize %s properly',
revertCode => {
expect(revertCode.getSerializedLength()).toBe(1);
@@ -20,6 +21,9 @@ describe('revert_code', () => {
expect(field).toMatchSnapshot();
expect(RevertCode.fromField(field)).toEqual(revertCode);
expect(RevertCode.fromFields([field])).toEqual(revertCode);
+
+ const json = jsonStringify(revertCode);
+ expect(RevertCode.schema.parse(JSON.parse(json))).toEqual(revertCode);
},
);
diff --git a/yarn-project/circuits.js/src/structs/revert_code.ts b/yarn-project/circuits.js/src/structs/revert_code.ts
index 55ac00d331c..7e4357f05ae 100644
--- a/yarn-project/circuits.js/src/structs/revert_code.ts
+++ b/yarn-project/circuits.js/src/structs/revert_code.ts
@@ -2,8 +2,9 @@ import { Fr } from '@aztec/foundation/fields';
import { BufferReader, FieldReader } from '@aztec/foundation/serialize';
import { inspect } from 'util';
+import { z } from 'zod';
-enum RevertCodeEnum {
+export enum RevertCodeEnum {
OK = 0,
APP_LOGIC_REVERTED = 1,
TEARDOWN_REVERTED = 2,
@@ -55,6 +56,14 @@ export class RevertCode {
}
}
+ public toJSON() {
+ return this.code;
+ }
+
+ static get schema() {
+ return z.nativeEnum(RevertCodeEnum).transform(value => new RevertCode(value));
+ }
+
/**
* Having different serialization methods allows for
* decoupling the serialization for producing the content commitment hash
diff --git a/yarn-project/circuits.js/src/structs/rollup/append_only_tree_snapshot.ts b/yarn-project/circuits.js/src/structs/rollup/append_only_tree_snapshot.ts
index b4c71e37be1..5a97560f2e9 100644
--- a/yarn-project/circuits.js/src/structs/rollup/append_only_tree_snapshot.ts
+++ b/yarn-project/circuits.js/src/structs/rollup/append_only_tree_snapshot.ts
@@ -1,11 +1,12 @@
import { Fr } from '@aztec/foundation/fields';
import { schemas } from '@aztec/foundation/schemas';
import { BufferReader, FieldReader, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { inspect } from 'util';
import { z } from 'zod';
-import { STRING_ENCODING, type UInt32 } from '../shared.js';
+import { type UInt32 } from '../shared.js';
/**
* Snapshot of an append only tree.
@@ -39,10 +40,6 @@ export class AppendOnlyTreeSnapshot {
.transform(({ root, nextAvailableLeafIndex }) => new AppendOnlyTreeSnapshot(root, nextAvailableLeafIndex));
}
- toJSON() {
- return { root: this.root, nextAvailableLeafIndex: this.nextAvailableLeafIndex };
- }
-
getSize() {
return this.root.size + 4;
}
@@ -56,7 +53,7 @@ export class AppendOnlyTreeSnapshot {
}
toString(): string {
- return this.toBuffer().toString(STRING_ENCODING);
+ return bufferToHex(this.toBuffer());
}
static fromBuffer(buffer: Buffer | BufferReader): AppendOnlyTreeSnapshot {
@@ -65,7 +62,7 @@ export class AppendOnlyTreeSnapshot {
}
static fromString(str: string): AppendOnlyTreeSnapshot {
- return AppendOnlyTreeSnapshot.fromBuffer(Buffer.from(str, STRING_ENCODING));
+ return AppendOnlyTreeSnapshot.fromBuffer(hexToBuffer(str));
}
static fromFields(fields: Fr[] | FieldReader): AppendOnlyTreeSnapshot {
diff --git a/yarn-project/circuits.js/src/structs/rollup/base_or_merge_rollup_public_inputs.ts b/yarn-project/circuits.js/src/structs/rollup/base_or_merge_rollup_public_inputs.ts
index 981d1f0faa6..c42337e1c0f 100644
--- a/yarn-project/circuits.js/src/structs/rollup/base_or_merge_rollup_public_inputs.ts
+++ b/yarn-project/circuits.js/src/structs/rollup/base_or_merge_rollup_public_inputs.ts
@@ -1,6 +1,7 @@
import { Fr } from '@aztec/foundation/fields';
-import { hexSchemaFor } from '@aztec/foundation/schemas';
+import { bufferSchemaFor } from '@aztec/foundation/schemas';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { PartialStateReference } from '../partial_state_reference.js';
import { RollupTypes } from '../shared.js';
@@ -108,7 +109,7 @@ export class BaseOrMergeRollupPublicInputs {
* @returns - The hex string.
*/
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
/**
@@ -117,16 +118,16 @@ export class BaseOrMergeRollupPublicInputs {
* @returns A new BaseOrMergeRollupPublicInputs instance.
*/
static fromString(str: string) {
- return BaseOrMergeRollupPublicInputs.fromBuffer(Buffer.from(str, 'hex'));
+ return BaseOrMergeRollupPublicInputs.fromBuffer(hexToBuffer(str));
}
- /** Returns a hex representation for JSON serialization. */
+ /** Returns a buffer representation for JSON serialization. */
toJSON() {
- return this.toString();
+ return this.toBuffer();
}
/** Creates an instance from a hex string. */
static get schema() {
- return hexSchemaFor(BaseOrMergeRollupPublicInputs);
+ return bufferSchemaFor(BaseOrMergeRollupPublicInputs);
}
}
diff --git a/yarn-project/circuits.js/src/structs/rollup/base_rollup_hints.ts b/yarn-project/circuits.js/src/structs/rollup/base_rollup_hints.ts
index d9176c82f6d..80f627b4fab 100644
--- a/yarn-project/circuits.js/src/structs/rollup/base_rollup_hints.ts
+++ b/yarn-project/circuits.js/src/structs/rollup/base_rollup_hints.ts
@@ -1,4 +1,5 @@
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { type FieldsOf } from '@aztec/foundation/types';
import { ARCHIVE_HEIGHT } from '../../constants.gen.js';
@@ -56,7 +57,7 @@ export class PrivateBaseRollupHints {
* @returns The instance serialized to a hex string.
*/
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
static fromBuffer(buffer: Buffer | BufferReader): PrivateBaseRollupHints {
@@ -71,7 +72,7 @@ export class PrivateBaseRollupHints {
}
static fromString(str: string) {
- return PrivateBaseRollupHints.fromBuffer(Buffer.from(str, 'hex'));
+ return PrivateBaseRollupHints.fromBuffer(hexToBuffer(str));
}
static empty() {
@@ -130,7 +131,7 @@ export class PublicBaseRollupHints {
* @returns The instance serialized to a hex string.
*/
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
static fromBuffer(buffer: Buffer | BufferReader): PublicBaseRollupHints {
@@ -145,7 +146,7 @@ export class PublicBaseRollupHints {
}
static fromString(str: string) {
- return PublicBaseRollupHints.fromBuffer(Buffer.from(str, 'hex'));
+ return PublicBaseRollupHints.fromBuffer(hexToBuffer(str));
}
static empty() {
diff --git a/yarn-project/circuits.js/src/structs/rollup/block_merge_rollup.ts b/yarn-project/circuits.js/src/structs/rollup/block_merge_rollup.ts
index 6732a4ffadf..e134ad16ba0 100644
--- a/yarn-project/circuits.js/src/structs/rollup/block_merge_rollup.ts
+++ b/yarn-project/circuits.js/src/structs/rollup/block_merge_rollup.ts
@@ -1,5 +1,6 @@
-import { hexSchemaFor } from '@aztec/foundation/schemas';
+import { bufferSchemaFor } from '@aztec/foundation/schemas';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { PreviousRollupBlockData } from './previous_rollup_block_data.js';
@@ -27,7 +28,7 @@ export class BlockMergeRollupInputs {
* @returns The instance serialized to a hex string.
*/
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
/**
@@ -49,16 +50,16 @@ export class BlockMergeRollupInputs {
* @returns A new BlockMergeRollupInputs instance.
*/
static fromString(str: string) {
- return BlockMergeRollupInputs.fromBuffer(Buffer.from(str, 'hex'));
+ return BlockMergeRollupInputs.fromBuffer(hexToBuffer(str));
}
/** Returns a hex representation for JSON serialization. */
toJSON() {
- return this.toString();
+ return this.toBuffer();
}
/** Creates an instance from a hex string. */
static get schema() {
- return hexSchemaFor(BlockMergeRollupInputs);
+ return bufferSchemaFor(BlockMergeRollupInputs);
}
}
diff --git a/yarn-project/circuits.js/src/structs/rollup/block_root_or_block_merge_public_inputs.ts b/yarn-project/circuits.js/src/structs/rollup/block_root_or_block_merge_public_inputs.ts
index 639f335b760..00eeb3666a7 100644
--- a/yarn-project/circuits.js/src/structs/rollup/block_root_or_block_merge_public_inputs.ts
+++ b/yarn-project/circuits.js/src/structs/rollup/block_root_or_block_merge_public_inputs.ts
@@ -1,7 +1,8 @@
import { EthAddress } from '@aztec/foundation/eth-address';
import { Fr } from '@aztec/foundation/fields';
-import { hexSchemaFor } from '@aztec/foundation/schemas';
+import { bufferSchemaFor } from '@aztec/foundation/schemas';
import { BufferReader, type Tuple, serializeToBuffer, serializeToFields } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { type FieldsOf } from '@aztec/foundation/types';
import { AZTEC_MAX_EPOCH_DURATION } from '../../constants.gen.js';
@@ -107,7 +108,7 @@ export class BlockRootOrBlockMergePublicInputs {
* @returns - The hex string.
*/
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
/**
@@ -116,17 +117,17 @@ export class BlockRootOrBlockMergePublicInputs {
* @returns A new BaseOrMergeRollupPublicInputs instance.
*/
static fromString(str: string) {
- return BlockRootOrBlockMergePublicInputs.fromBuffer(Buffer.from(str, 'hex'));
+ return BlockRootOrBlockMergePublicInputs.fromBuffer(hexToBuffer(str));
}
- /** Returns a hex representation for JSON serialization. */
+ /** Returns a buffer representation for JSON serialization. */
toJSON() {
- return this.toString();
+ return this.toBuffer();
}
/** Creates an instance from a hex string. */
static get schema() {
- return hexSchemaFor(BlockRootOrBlockMergePublicInputs);
+ return bufferSchemaFor(BlockRootOrBlockMergePublicInputs);
}
}
diff --git a/yarn-project/circuits.js/src/structs/rollup/block_root_rollup.ts b/yarn-project/circuits.js/src/structs/rollup/block_root_rollup.ts
index 3a63c40ddb3..18c1c289cb2 100644
--- a/yarn-project/circuits.js/src/structs/rollup/block_root_rollup.ts
+++ b/yarn-project/circuits.js/src/structs/rollup/block_root_rollup.ts
@@ -1,6 +1,7 @@
import { Fr } from '@aztec/foundation/fields';
-import { hexSchemaFor } from '@aztec/foundation/schemas';
+import { bufferSchemaFor } from '@aztec/foundation/schemas';
import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { type FieldsOf } from '@aztec/foundation/types';
import {
@@ -69,7 +70,7 @@ export class BlockRootRollupInputs {
* @returns The instance serialized to a hex string.
*/
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
/**
@@ -126,16 +127,16 @@ export class BlockRootRollupInputs {
* @returns A new RootRollupInputs instance.
*/
static fromString(str: string) {
- return BlockRootRollupInputs.fromBuffer(Buffer.from(str, 'hex'));
+ return BlockRootRollupInputs.fromBuffer(hexToBuffer(str));
}
- /** Returns a hex representation for JSON serialization. */
+ /** Returns a buffer representation for JSON serialization. */
toJSON() {
- return this.toString();
+ return this.toBuffer();
}
/** Creates an instance from a hex string. */
static get schema() {
- return hexSchemaFor(BlockRootRollupInputs);
+ return bufferSchemaFor(BlockRootRollupInputs);
}
}
diff --git a/yarn-project/circuits.js/src/structs/rollup/empty_block_root_rollup_inputs.ts b/yarn-project/circuits.js/src/structs/rollup/empty_block_root_rollup_inputs.ts
index ba42802e1ae..f4355e835a7 100644
--- a/yarn-project/circuits.js/src/structs/rollup/empty_block_root_rollup_inputs.ts
+++ b/yarn-project/circuits.js/src/structs/rollup/empty_block_root_rollup_inputs.ts
@@ -1,6 +1,7 @@
import { Fr } from '@aztec/foundation/fields';
-import { hexSchemaFor } from '@aztec/foundation/schemas';
+import { bufferSchemaFor } from '@aztec/foundation/schemas';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { type FieldsOf } from '@aztec/foundation/types';
import { GlobalVariables } from '../global_variables.js';
@@ -33,7 +34,7 @@ export class EmptyBlockRootRollupInputs {
* @returns The instance serialized to a hex string.
*/
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
/**
@@ -84,16 +85,16 @@ export class EmptyBlockRootRollupInputs {
* @returns A new RootRollupInputs instance.
*/
static fromString(str: string) {
- return EmptyBlockRootRollupInputs.fromBuffer(Buffer.from(str, 'hex'));
+ return EmptyBlockRootRollupInputs.fromBuffer(hexToBuffer(str));
}
- /** Returns a hex representation for JSON serialization. */
+ /** Returns a buffer representation for JSON serialization. */
toJSON() {
- return this.toString();
+ return this.toBuffer();
}
- /** Creates an instance from a hex string. */
+ /** Creates an instance from a buffer string. */
static get schema() {
- return hexSchemaFor(EmptyBlockRootRollupInputs);
+ return bufferSchemaFor(EmptyBlockRootRollupInputs);
}
}
diff --git a/yarn-project/circuits.js/src/structs/rollup/merge_rollup.ts b/yarn-project/circuits.js/src/structs/rollup/merge_rollup.ts
index 2950f2f1614..2b38a5f6188 100644
--- a/yarn-project/circuits.js/src/structs/rollup/merge_rollup.ts
+++ b/yarn-project/circuits.js/src/structs/rollup/merge_rollup.ts
@@ -1,5 +1,6 @@
-import { hexSchemaFor } from '@aztec/foundation/schemas';
+import { bufferSchemaFor } from '@aztec/foundation/schemas';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { PreviousRollupData } from './previous_rollup_data.js';
@@ -27,7 +28,7 @@ export class MergeRollupInputs {
* @returns The instance serialized to a hex string.
*/
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
/**
@@ -46,16 +47,16 @@ export class MergeRollupInputs {
* @returns A new MergeRollupInputs instance.
*/
static fromString(str: string) {
- return MergeRollupInputs.fromBuffer(Buffer.from(str, 'hex'));
+ return MergeRollupInputs.fromBuffer(hexToBuffer(str));
}
- /** Returns a hex representation for JSON serialization. */
+ /** Returns a buffer representation for JSON serialization. */
toJSON() {
- return this.toString();
+ return this.toBuffer();
}
- /** Creates an instance from a hex string. */
+ /** Creates an instance from a string. */
static get schema() {
- return hexSchemaFor(MergeRollupInputs);
+ return bufferSchemaFor(MergeRollupInputs);
}
}
diff --git a/yarn-project/circuits.js/src/structs/rollup/private_base_rollup_inputs.ts b/yarn-project/circuits.js/src/structs/rollup/private_base_rollup_inputs.ts
index 1d354861e1a..a83a6655e28 100644
--- a/yarn-project/circuits.js/src/structs/rollup/private_base_rollup_inputs.ts
+++ b/yarn-project/circuits.js/src/structs/rollup/private_base_rollup_inputs.ts
@@ -1,5 +1,6 @@
-import { hexSchemaFor } from '@aztec/foundation/schemas';
+import { bufferSchemaFor } from '@aztec/foundation/schemas';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { type FieldsOf } from '@aztec/foundation/types';
import { PrivateBaseRollupHints } from './base_rollup_hints.js';
@@ -26,24 +27,24 @@ export class PrivateBaseRollupInputs {
}
static fromString(str: string) {
- return PrivateBaseRollupInputs.fromBuffer(Buffer.from(str, 'hex'));
+ return PrivateBaseRollupInputs.fromBuffer(hexToBuffer(str));
}
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
static empty() {
return new PrivateBaseRollupInputs(PrivateTubeData.empty(), PrivateBaseRollupHints.empty());
}
- /** Returns a hex representation for JSON serialization. */
+ /** Returns a buffer representation for JSON serialization. */
toJSON() {
- return this.toString();
+ return this.toBuffer();
}
/** Creates an instance from a hex string. */
static get schema() {
- return hexSchemaFor(PrivateBaseRollupInputs);
+ return bufferSchemaFor(PrivateBaseRollupInputs);
}
}
diff --git a/yarn-project/circuits.js/src/structs/rollup/public_base_rollup_inputs.ts b/yarn-project/circuits.js/src/structs/rollup/public_base_rollup_inputs.ts
index 1fa11ed3688..2bf644f4b81 100644
--- a/yarn-project/circuits.js/src/structs/rollup/public_base_rollup_inputs.ts
+++ b/yarn-project/circuits.js/src/structs/rollup/public_base_rollup_inputs.ts
@@ -1,5 +1,6 @@
-import { hexSchemaFor } from '@aztec/foundation/schemas';
+import { bufferSchemaFor } from '@aztec/foundation/schemas';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { type FieldsOf } from '@aztec/foundation/types';
import { AvmProofData } from './avm_proof_data.js';
@@ -33,25 +34,26 @@ export class PublicBaseRollupInputs {
toBuffer() {
return serializeToBuffer(...PublicBaseRollupInputs.getFields(this));
}
+
static fromString(str: string) {
- return PublicBaseRollupInputs.fromBuffer(Buffer.from(str, 'hex'));
+ return PublicBaseRollupInputs.fromBuffer(hexToBuffer(str));
}
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
static empty() {
return new PublicBaseRollupInputs(PublicTubeData.empty(), AvmProofData.empty(), PublicBaseRollupHints.empty());
}
- /** Returns a hex representation for JSON serialization. */
+ /** Returns a representation for JSON serialization. */
toJSON() {
- return this.toString();
+ return this.toBuffer();
}
- /** Creates an instance from a hex string. */
+ /** Creates an instance from a string. */
static get schema() {
- return hexSchemaFor(PublicBaseRollupInputs);
+ return bufferSchemaFor(PublicBaseRollupInputs);
}
}
diff --git a/yarn-project/circuits.js/src/structs/rollup/root_rollup.ts b/yarn-project/circuits.js/src/structs/rollup/root_rollup.ts
index a8eb8b433e5..180bfbdcc30 100644
--- a/yarn-project/circuits.js/src/structs/rollup/root_rollup.ts
+++ b/yarn-project/circuits.js/src/structs/rollup/root_rollup.ts
@@ -1,6 +1,7 @@
import { Fr } from '@aztec/foundation/fields';
-import { hexSchemaFor } from '@aztec/foundation/schemas';
+import { bufferSchemaFor } from '@aztec/foundation/schemas';
import { BufferReader, type Tuple, serializeToBuffer, serializeToFields } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { type FieldsOf } from '@aztec/foundation/types';
import { AZTEC_MAX_EPOCH_DURATION } from '../../constants.gen.js';
@@ -36,7 +37,7 @@ export class RootRollupInputs {
* @returns The instance serialized to a hex string.
*/
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
/**
@@ -76,17 +77,17 @@ export class RootRollupInputs {
* @returns A new RootRollupInputs instance.
*/
static fromString(str: string) {
- return RootRollupInputs.fromBuffer(Buffer.from(str, 'hex'));
+ return RootRollupInputs.fromBuffer(hexToBuffer(str));
}
- /** Returns a hex representation for JSON serialization. */
+ /** Returns a representation for JSON serialization. */
toJSON() {
- return this.toString();
+ return this.toBuffer();
}
- /** Creates an instance from a hex string. */
+ /** Creates an instance from a string. */
static get schema() {
- return hexSchemaFor(RootRollupInputs);
+ return bufferSchemaFor(RootRollupInputs);
}
}
@@ -163,20 +164,20 @@ export class RootRollupPublicInputs {
}
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
static fromString(str: string) {
- return RootRollupPublicInputs.fromBuffer(Buffer.from(str, 'hex'));
+ return RootRollupPublicInputs.fromBuffer(hexToBuffer(str));
}
- /** Returns a hex representation for JSON serialization. */
+ /** Returns a representation for JSON serialization. */
toJSON() {
- return this.toString();
+ return this.toBuffer();
}
- /** Creates an instance from a hex string. */
+ /** Creates an instance from a string. */
static get schema() {
- return hexSchemaFor(RootRollupPublicInputs);
+ return bufferSchemaFor(RootRollupPublicInputs);
}
}
diff --git a/yarn-project/circuits.js/src/structs/rollup/tube_inputs.ts b/yarn-project/circuits.js/src/structs/rollup/tube_inputs.ts
index 0320d0ec228..86a58efbaf8 100644
--- a/yarn-project/circuits.js/src/structs/rollup/tube_inputs.ts
+++ b/yarn-project/circuits.js/src/structs/rollup/tube_inputs.ts
@@ -1,5 +1,6 @@
-import { hexSchemaFor } from '@aztec/foundation/schemas';
+import { bufferSchemaFor } from '@aztec/foundation/schemas';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { type FieldsOf } from '@aztec/foundation/types';
import { ClientIvcProof } from '../client_ivc_proof.js';
@@ -28,7 +29,7 @@ export class TubeInputs {
* @returns The instance serialized to a hex string.
*/
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
/**
@@ -50,7 +51,7 @@ export class TubeInputs {
* @returns A new TubeInputs instance.
*/
static fromString(str: string) {
- return TubeInputs.fromBuffer(Buffer.from(str, 'hex'));
+ return TubeInputs.fromBuffer(hexToBuffer(str));
}
static empty() {
@@ -59,11 +60,11 @@ export class TubeInputs {
/** Returns a hex representation for JSON serialization. */
toJSON() {
- return this.toString();
+ return this.toBuffer();
}
/** Creates an instance from a hex string. */
static get schema() {
- return hexSchemaFor(TubeInputs);
+ return bufferSchemaFor(TubeInputs);
}
}
diff --git a/yarn-project/circuits.js/src/structs/rollup_validation_requests.ts b/yarn-project/circuits.js/src/structs/rollup_validation_requests.ts
index 4113649893d..2d2279b8c88 100644
--- a/yarn-project/circuits.js/src/structs/rollup_validation_requests.ts
+++ b/yarn-project/circuits.js/src/structs/rollup_validation_requests.ts
@@ -1,5 +1,6 @@
import { type Fr } from '@aztec/foundation/fields';
import { BufferReader, FieldReader, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { MaxBlockNumber } from './max_block_number.js';
@@ -23,7 +24,7 @@ export class RollupValidationRequests {
}
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
static fromFields(fields: Fr[] | FieldReader) {
@@ -47,7 +48,7 @@ export class RollupValidationRequests {
* @returns Deserialized object.
*/
static fromString(str: string) {
- return RollupValidationRequests.fromBuffer(Buffer.from(str, 'hex'));
+ return RollupValidationRequests.fromBuffer(hexToBuffer(str));
}
static empty() {
diff --git a/yarn-project/circuits.js/src/structs/shared.ts b/yarn-project/circuits.js/src/structs/shared.ts
index c8cce1576fe..ae40dd95953 100644
--- a/yarn-project/circuits.js/src/structs/shared.ts
+++ b/yarn-project/circuits.js/src/structs/shared.ts
@@ -43,8 +43,3 @@ export enum RollupTypes {
Merge = 1,
Root = 2,
}
-
-/**
- * String encoding of serialized buffer data
- */
-export const STRING_ENCODING: BufferEncoding = 'hex';
diff --git a/yarn-project/circuits.js/src/structs/state_reference.ts b/yarn-project/circuits.js/src/structs/state_reference.ts
index 8f0c1fd0be0..49e91ac5324 100644
--- a/yarn-project/circuits.js/src/structs/state_reference.ts
+++ b/yarn-project/circuits.js/src/structs/state_reference.ts
@@ -19,10 +19,6 @@ export class StateReference {
public partial: PartialStateReference,
) {}
- toJSON() {
- return { l1ToL2MessageTree: this.l1ToL2MessageTree, partial: this.partial };
- }
-
static get schema() {
return z
.object({
diff --git a/yarn-project/circuits.js/src/structs/trees/nullifier_leaf.ts b/yarn-project/circuits.js/src/structs/trees/nullifier_leaf.ts
index 8d561e1ebfb..52b8be14aec 100644
--- a/yarn-project/circuits.js/src/structs/trees/nullifier_leaf.ts
+++ b/yarn-project/circuits.js/src/structs/trees/nullifier_leaf.ts
@@ -38,14 +38,6 @@ export class NullifierLeafPreimage implements IndexedTreeLeafPreimage {
);
}
- toJSON() {
- return {
- nullifier: this.nullifier.toString(),
- nextNullifier: this.nextNullifier.toString(),
- nextIndex: '0x' + this.nextIndex.toString(16),
- };
- }
-
getKey(): bigint {
return this.nullifier.toBigInt();
}
@@ -102,14 +94,6 @@ export class NullifierLeafPreimage implements IndexedTreeLeafPreimage {
static clone(preimage: NullifierLeafPreimage): NullifierLeafPreimage {
return new NullifierLeafPreimage(preimage.nullifier, preimage.nextNullifier, preimage.nextIndex);
}
-
- static fromJSON(json: any): NullifierLeafPreimage {
- return new NullifierLeafPreimage(
- Fr.fromString(json.nullifier),
- Fr.fromString(json.nextNullifier),
- BigInt(json.nextIndex),
- );
- }
}
/**
diff --git a/yarn-project/circuits.js/src/structs/tx_context.ts b/yarn-project/circuits.js/src/structs/tx_context.ts
index 526ff0860ef..33234b4417a 100644
--- a/yarn-project/circuits.js/src/structs/tx_context.ts
+++ b/yarn-project/circuits.js/src/structs/tx_context.ts
@@ -37,14 +37,6 @@ export class TxContext {
.transform(TxContext.from);
}
- toJSON() {
- return {
- chainId: this.chainId,
- version: this.version,
- gasSettings: this.gasSettings,
- };
- }
-
getSize() {
return this.chainId.size + this.version.size + this.gasSettings.getSize();
}
diff --git a/yarn-project/circuits.js/src/structs/verification_key.ts b/yarn-project/circuits.js/src/structs/verification_key.ts
index 22aa2d68e04..f3fc4a27610 100644
--- a/yarn-project/circuits.js/src/structs/verification_key.ts
+++ b/yarn-project/circuits.js/src/structs/verification_key.ts
@@ -1,8 +1,9 @@
import { makeTuple } from '@aztec/foundation/array';
import { times } from '@aztec/foundation/collection';
import { Fq, Fr } from '@aztec/foundation/fields';
-import { hexSchemaFor } from '@aztec/foundation/schemas';
+import { bufferSchemaFor } from '@aztec/foundation/schemas';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
import { HONK_VERIFICATION_KEY_LENGTH_IN_FIELDS } from '../constants.gen.js';
import { CircuitType } from './shared.js';
@@ -100,11 +101,11 @@ export class VerificationKeyAsFields {
static get schema() {
// TODO(palla/schemas): Should we verify the hash matches the key when deserializing?
- return hexSchemaFor(VerificationKeyAsFields);
+ return bufferSchemaFor(VerificationKeyAsFields);
}
toJSON() {
- return '0x' + this.toBuffer().toString('hex');
+ return this.toBuffer();
}
/**
@@ -261,7 +262,7 @@ export class VerificationKeyData {
}
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
static fromBuffer(buffer: Buffer | BufferReader): VerificationKeyData {
@@ -273,7 +274,7 @@ export class VerificationKeyData {
}
static fromString(str: string): VerificationKeyData {
- return VerificationKeyData.fromBuffer(Buffer.from(str, 'hex'));
+ return VerificationKeyData.fromBuffer(hexToBuffer(str));
}
public clone() {
@@ -282,11 +283,11 @@ export class VerificationKeyData {
/** Returns a hex representation for JSON serialization. */
toJSON() {
- return this.toString();
+ return this.toBuffer();
}
/** Creates an instance from a hex string. */
static get schema() {
- return hexSchemaFor(VerificationKeyData);
+ return bufferSchemaFor(VerificationKeyData);
}
}
diff --git a/yarn-project/circuits.js/src/structs/vk_witness_data.ts b/yarn-project/circuits.js/src/structs/vk_witness_data.ts
index 723475b5fa2..90e2239cd65 100644
--- a/yarn-project/circuits.js/src/structs/vk_witness_data.ts
+++ b/yarn-project/circuits.js/src/structs/vk_witness_data.ts
@@ -1,6 +1,7 @@
import { makeTuple } from '@aztec/foundation/array';
import { Fr } from '@aztec/foundation/fields';
import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex } from '@aztec/foundation/string';
import { VK_TREE_HEIGHT } from '../constants.gen.js';
import { type UInt32 } from './shared.js';
@@ -37,6 +38,6 @@ export class VkWitnessData {
}
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
}
diff --git a/yarn-project/circuits.js/src/types/public_keys.ts b/yarn-project/circuits.js/src/types/public_keys.ts
index 321fc04c7a3..d426ab2f3b8 100644
--- a/yarn-project/circuits.js/src/types/public_keys.ts
+++ b/yarn-project/circuits.js/src/types/public_keys.ts
@@ -2,6 +2,7 @@ import { poseidon2HashWithSeparator } from '@aztec/foundation/crypto';
import { Fr, Point } from '@aztec/foundation/fields';
import { schemas } from '@aztec/foundation/schemas';
import { BufferReader, FieldReader, serializeToBuffer } from '@aztec/foundation/serialize';
+import { bufferToHex } from '@aztec/foundation/string';
import { type FieldsOf } from '@aztec/foundation/types';
import { z } from 'zod';
@@ -184,7 +185,7 @@ export class PublicKeys {
}
toString() {
- return this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
static fromString(keys: string) {
diff --git a/yarn-project/cli-wallet/src/cmds/cancel_tx.ts b/yarn-project/cli-wallet/src/cmds/cancel_tx.ts
index c0fb4812f77..2d6ae924075 100644
--- a/yarn-project/cli-wallet/src/cmds/cancel_tx.ts
+++ b/yarn-project/cli-wallet/src/cmds/cancel_tx.ts
@@ -45,7 +45,7 @@ export async function cancelTx(
log(` Tx fee: ${cancelReceipt.transactionFee}`);
log(` Status: ${cancelReceipt.status}`);
log(` Block number: ${cancelReceipt.blockNumber}`);
- log(` Block hash: ${cancelReceipt.blockHash?.toString('hex')}`);
+ log(` Block hash: ${cancelReceipt.blockHash?.toString()}`);
} catch (err: any) {
log(`Could not cancel transaction\n ${err.message}`);
}
diff --git a/yarn-project/cli-wallet/src/cmds/send.ts b/yarn-project/cli-wallet/src/cmds/send.ts
index fa6af43fa93..b87097ec125 100644
--- a/yarn-project/cli-wallet/src/cmds/send.ts
+++ b/yarn-project/cli-wallet/src/cmds/send.ts
@@ -42,7 +42,7 @@ export async function send(
log(` Tx fee: ${receipt.transactionFee}`);
log(` Status: ${receipt.status}`);
log(` Block number: ${receipt.blockNumber}`);
- log(` Block hash: ${receipt.blockHash?.toString('hex')}`);
+ log(` Block hash: ${receipt.blockHash?.toString()}`);
} catch (err: any) {
log(`Transaction failed\n ${err.message}`);
}
diff --git a/yarn-project/cli/src/cmds/infrastructure/setup_protocol_contract.ts b/yarn-project/cli/src/cmds/infrastructure/setup_protocol_contract.ts
index 113bfea6a09..a7473487d31 100644
--- a/yarn-project/cli/src/cmds/infrastructure/setup_protocol_contract.ts
+++ b/yarn-project/cli/src/cmds/infrastructure/setup_protocol_contract.ts
@@ -1,5 +1,6 @@
import { SignerlessWallet, type WaitOpts, createPXEClient, makeFetch } from '@aztec/aztec.js';
import { DefaultMultiCallEntrypoint } from '@aztec/aztec.js/entrypoint';
+import { jsonStringify } from '@aztec/foundation/json-rpc';
import { type LogFn } from '@aztec/foundation/log';
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
@@ -18,7 +19,7 @@ export async function setupProtocolContracts(
proven: !skipProofWait,
provenTimeout: 600,
};
- log('setupProtocolContracts: Wait options' + JSON.stringify(waitOpts));
+ log('setupProtocolContracts: Wait options' + jsonStringify(waitOpts));
log('setupProtocolContracts: Creating PXE client...');
const pxe = createPXEClient(rpcUrl, makeFetch([1, 1, 1, 1, 1], false));
const wallet = new SignerlessWallet(pxe, new DefaultMultiCallEntrypoint(l1ChainId, 1));
diff --git a/yarn-project/cli/src/cmds/pxe/get_current_base_fee.ts b/yarn-project/cli/src/cmds/pxe/get_current_base_fee.ts
index 1d64ad585f2..c736a4766b6 100644
--- a/yarn-project/cli/src/cmds/pxe/get_current_base_fee.ts
+++ b/yarn-project/cli/src/cmds/pxe/get_current_base_fee.ts
@@ -1,8 +1,9 @@
import { createCompatibleClient } from '@aztec/aztec.js';
+import { jsonStringify } from '@aztec/foundation/json-rpc';
import { type DebugLogger, type LogFn } from '@aztec/foundation/log';
export async function getCurrentBaseFee(rpcUrl: string, debugLogger: DebugLogger, log: LogFn) {
const client = await createCompatibleClient(rpcUrl, debugLogger);
const fees = await client.getCurrentBaseFees();
- log(`Current fees: ${JSON.stringify(fees.toJSON())}`);
+ log(`Current fees: ${jsonStringify(fees)}`);
}
diff --git a/yarn-project/cli/src/utils/inspect.ts b/yarn-project/cli/src/utils/inspect.ts
index 855c38b9ef5..77d6c067a7e 100644
--- a/yarn-project/cli/src/utils/inspect.ts
+++ b/yarn-project/cli/src/utils/inspect.ts
@@ -58,7 +58,7 @@ export async function inspectTx(
const artifactMap = opts?.artifactMap ?? (await getKnownArtifacts(pxe));
if (opts.includeBlockInfo) {
- log(` Block: ${receipt.blockNumber} (${receipt.blockHash?.toString('hex')})`);
+ log(` Block: ${receipt.blockNumber} (${receipt.blockHash?.toString()})`);
}
if (receipt.transactionFee) {
log(` Fee: ${receipt.transactionFee.toString()}`);
diff --git a/yarn-project/end-to-end/src/e2e_fees/failures.test.ts b/yarn-project/end-to-end/src/e2e_fees/failures.test.ts
index dcacb4ca441..664f920873d 100644
--- a/yarn-project/end-to-end/src/e2e_fees/failures.test.ts
+++ b/yarn-project/end-to-end/src/e2e_fees/failures.test.ts
@@ -242,7 +242,7 @@ describe('e2e_fees failures', () => {
},
})
.wait(),
- ).rejects.toThrow(/Transaction [0-9a-f]{64} was dropped\. Reason: Tx dropped by P2P node\./);
+ ).rejects.toThrow(/Transaction (0x)?[0-9a-fA-F]{64} was dropped\. Reason: Tx dropped by P2P node\./);
});
it('includes transaction that error in teardown', async () => {
diff --git a/yarn-project/end-to-end/src/e2e_prover/e2e_prover_test.ts b/yarn-project/end-to-end/src/e2e_prover/e2e_prover_test.ts
index 15e77e4e775..e2d230a40a2 100644
--- a/yarn-project/end-to-end/src/e2e_prover/e2e_prover_test.ts
+++ b/yarn-project/end-to-end/src/e2e_prover/e2e_prover_test.ts
@@ -253,7 +253,7 @@ export class FullProverTest {
// The simulated prover node (now shutdown) used private key index 2
const proverNodePrivateKey = getPrivateKeyFromIndex(2);
- const proverNodeSenderAddress = privateKeyToAddress(new Buffer32(proverNodePrivateKey!).to0xString());
+ const proverNodeSenderAddress = privateKeyToAddress(new Buffer32(proverNodePrivateKey!).toString());
this.proverAddress = EthAddress.fromString(proverNodeSenderAddress);
this.logger.verbose(`Funding prover node at ${proverNodeSenderAddress}`);
diff --git a/yarn-project/end-to-end/src/fixtures/snapshot_manager.ts b/yarn-project/end-to-end/src/fixtures/snapshot_manager.ts
index 3a85d0ff79b..6f58a48dda6 100644
--- a/yarn-project/end-to-end/src/fixtures/snapshot_manager.ts
+++ b/yarn-project/end-to-end/src/fixtures/snapshot_manager.ts
@@ -368,7 +368,7 @@ async function setupFromFresh(
const cheatCodes = await CheatCodes.create(aztecNodeConfig.l1RpcUrl, pxe);
if (statePath) {
- writeFileSync(`${statePath}/aztec_node_config.json`, JSON.stringify(aztecNodeConfig));
+ writeFileSync(`${statePath}/aztec_node_config.json`, JSON.stringify(aztecNodeConfig, resolver));
}
return {
@@ -497,7 +497,7 @@ export const addAccounts =
logger.verbose('Account deployment tx hashes:');
for (const provenTx of provenTxs) {
- logger.verbose(provenTx.getTxHash().to0xString());
+ logger.verbose(provenTx.getTxHash().toString());
}
logger.verbose('Deploying accounts...');
diff --git a/yarn-project/end-to-end/src/prover-coordination/e2e_prover_coordination.test.ts b/yarn-project/end-to-end/src/prover-coordination/e2e_prover_coordination.test.ts
index 665abe523dc..6ec6832ff53 100644
--- a/yarn-project/end-to-end/src/prover-coordination/e2e_prover_coordination.test.ts
+++ b/yarn-project/end-to-end/src/prover-coordination/e2e_prover_coordination.test.ts
@@ -112,7 +112,7 @@ describe('e2e_prover_coordination', () => {
const proverKey = Buffer32.random();
proverSigner = new Secp256k1Signer(proverKey);
proverWallet = createWalletClient({
- account: privateKeyToAccount(proverKey.to0xString()),
+ account: privateKeyToAccount(proverKey.toString()),
chain: foundry,
transport: http(ctx.aztecNodeConfig.l1RpcUrl),
});
diff --git a/yarn-project/foundation/src/abi/abi.ts b/yarn-project/foundation/src/abi/abi.ts
index 2f13d6ab67a..4ba09fb11a9 100644
--- a/yarn-project/foundation/src/abi/abi.ts
+++ b/yarn-project/foundation/src/abi/abi.ts
@@ -230,7 +230,7 @@ export interface FunctionArtifact extends FunctionAbi {
export const FunctionArtifactSchema = FunctionAbiSchema.and(
z.object({
- bytecode: schemas.BufferB64,
+ bytecode: schemas.Buffer,
verificationKey: z.string().optional(),
debugSymbols: z.string(),
debug: FunctionDebugMetadataSchema.optional(),
diff --git a/yarn-project/foundation/src/abi/encoder.test.ts b/yarn-project/foundation/src/abi/encoder.test.ts
index 0f1e6841cba..0b901d030ef 100644
--- a/yarn-project/foundation/src/abi/encoder.test.ts
+++ b/yarn-project/foundation/src/abi/encoder.test.ts
@@ -1,7 +1,7 @@
import { AztecAddress } from '../aztec-address/index.js';
import { Fr } from '../fields/fields.js';
import { Point } from '../fields/point.js';
-import { jsonParseWithSchema } from '../json-rpc/convert.js';
+import { jsonParseWithSchema, jsonStringify } from '../json-rpc/convert.js';
import { schemas } from '../schemas/schemas.js';
import { type FunctionAbi, FunctionType } from './abi.js';
import { encodeArguments } from './encoder.js';
@@ -30,7 +30,7 @@ describe('abi/encoder', () => {
const field = Fr.random();
expect(encodeArguments(abi, [field])).toEqual([field]);
- const serializedField = jsonParseWithSchema(JSON.stringify(field), schemas.Fr);
+ const serializedField = jsonParseWithSchema(jsonStringify(field), schemas.Fr);
expect(encodeArguments(abi, [serializedField])).toEqual([field]);
});
@@ -122,7 +122,7 @@ describe('abi/encoder', () => {
const completeAddressLike = { address, publicKey: Point.random(), partialAddress: Fr.random() };
expect(encodeArguments(abi, [completeAddressLike])).toEqual([address.toField()]);
- const serializedAddress = jsonParseWithSchema(JSON.stringify(address), schemas.AztecAddress);
+ const serializedAddress = jsonParseWithSchema(jsonStringify(address), schemas.AztecAddress);
expect(encodeArguments(abi, [serializedAddress])).toEqual([address.toField()]);
});
diff --git a/yarn-project/foundation/src/abi/event_selector.ts b/yarn-project/foundation/src/abi/event_selector.ts
index ea4d8bd234c..0203d562380 100644
--- a/yarn-project/foundation/src/abi/event_selector.ts
+++ b/yarn-project/foundation/src/abi/event_selector.ts
@@ -1,6 +1,7 @@
import { fromHex, toBigIntBE } from '../bigint-buffer/index.js';
import { poseidon2HashBytes, randomBytes } from '../crypto/index.js';
import { type Fr } from '../fields/fields.js';
+import { hexSchemaFor } from '../schemas/utils.js';
import { BufferReader } from '../serialize/buffer_reader.js';
import { Selector } from './selector.js';
@@ -83,9 +84,10 @@ export class EventSelector extends Selector {
}
toJSON() {
- return {
- type: 'EventSelector',
- value: this.toString(),
- };
+ return this.toString();
+ }
+
+ static get schema() {
+ return hexSchemaFor(EventSelector);
}
}
diff --git a/yarn-project/foundation/src/abi/function_selector.ts b/yarn-project/foundation/src/abi/function_selector.ts
index 7641234f9ab..00b75d1b500 100644
--- a/yarn-project/foundation/src/abi/function_selector.ts
+++ b/yarn-project/foundation/src/abi/function_selector.ts
@@ -1,6 +1,7 @@
import { fromHex, toBigIntBE } from '../bigint-buffer/index.js';
import { poseidon2HashBytes, randomBytes } from '../crypto/index.js';
import { type Fr } from '../fields/fields.js';
+import { hexSchemaFor } from '../schemas/utils.js';
import { BufferReader } from '../serialize/buffer_reader.js';
import { FieldReader } from '../serialize/field_reader.js';
import { TypeRegistry } from '../serialize/type_registry.js';
@@ -132,10 +133,11 @@ export class FunctionSelector extends Selector {
}
toJSON() {
- return {
- type: 'FunctionSelector',
- value: this.toString(),
- };
+ return this.toString();
+ }
+
+ static get schema() {
+ return hexSchemaFor(FunctionSelector);
}
}
diff --git a/yarn-project/foundation/src/abi/note_selector.ts b/yarn-project/foundation/src/abi/note_selector.ts
index 8fdcaa945c3..10f784620f1 100644
--- a/yarn-project/foundation/src/abi/note_selector.ts
+++ b/yarn-project/foundation/src/abi/note_selector.ts
@@ -1,6 +1,7 @@
import { toBigIntBE } from '../bigint-buffer/index.js';
import { randomBytes } from '../crypto/index.js';
import { type Fr } from '../fields/fields.js';
+import { hexSchemaFor } from '../schemas/utils.js';
import { BufferReader } from '../serialize/buffer_reader.js';
import { TypeRegistry } from '../serialize/type_registry.js';
import { Selector } from './selector.js';
@@ -58,14 +59,11 @@ export class NoteSelector extends Selector {
}
toJSON() {
- return {
- type: 'NoteSelector',
- value: this.toString(),
- };
+ return this.toString();
}
- static fromJSON(json: any): NoteSelector {
- return NoteSelector.fromString(json.value);
+ static get schema() {
+ return hexSchemaFor(NoteSelector);
}
}
diff --git a/yarn-project/foundation/src/abi/selector.ts b/yarn-project/foundation/src/abi/selector.ts
index e8f56e01093..9ee416654b3 100644
--- a/yarn-project/foundation/src/abi/selector.ts
+++ b/yarn-project/foundation/src/abi/selector.ts
@@ -2,6 +2,7 @@ import { inspect } from 'util';
import { toBufferBE } from '../bigint-buffer/index.js';
import { Fr } from '../fields/index.js';
+import { bufferToHex } from '../string/index.js';
/** A selector is the first 4 bytes of the hash of a signature. */
export abstract class Selector {
@@ -36,7 +37,7 @@ export abstract class Selector {
* @returns The string.
*/
toString(): string {
- return '0x' + this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
[inspect.custom]() {
diff --git a/yarn-project/foundation/src/aztec-address/index.ts b/yarn-project/foundation/src/aztec-address/index.ts
index d58fd9b0d77..fe965da95e1 100644
--- a/yarn-project/foundation/src/aztec-address/index.ts
+++ b/yarn-project/foundation/src/aztec-address/index.ts
@@ -2,6 +2,7 @@
import { inspect } from 'util';
import { Fr, Point, fromBuffer } from '../fields/index.js';
+import { hexSchemaFor } from '../schemas/utils.js';
import { type BufferReader, FieldReader } from '../serialize/index.js';
import { TypeRegistry } from '../serialize/type_registry.js';
import { hexToBuffer } from '../string/index.js';
@@ -133,10 +134,11 @@ export class AztecAddress {
}
toJSON() {
- return {
- type: 'AztecAddress',
- value: this.toString(),
- };
+ return this.toString();
+ }
+
+ static get schema() {
+ return hexSchemaFor(AztecAddress, AztecAddress.isAddress);
}
}
diff --git a/yarn-project/foundation/src/buffer/buffer32.ts b/yarn-project/foundation/src/buffer/buffer32.ts
index 4b1c2e1c25d..799df3f27ec 100644
--- a/yarn-project/foundation/src/buffer/buffer32.ts
+++ b/yarn-project/foundation/src/buffer/buffer32.ts
@@ -2,6 +2,8 @@ import { randomBytes } from '@aztec/foundation/crypto';
import { type Fr } from '@aztec/foundation/fields';
import { BufferReader, deserializeBigInt, serializeBigInt } from '@aztec/foundation/serialize';
+import { bufferToHex } from '../string/index.js';
+
/**
* A class representing a 32 byte Buffer.
*/
@@ -67,17 +69,13 @@ export class Buffer32 {
* @returns The hex string.
*/
public toString() {
- return this.buffer.toString('hex');
+ return bufferToHex(this.buffer);
}
toJSON() {
return this.toString();
}
- public to0xString(): `0x${string}` {
- return `0x${this.buffer.toString('hex')}`;
- }
-
/**
* Convert this hash to a big int.
* @returns The big int.
@@ -117,18 +115,6 @@ export class Buffer32 {
* @param str - The TX hash in string format.
* @returns A new Buffer32 object.
*/
- public static fromStringUnchecked(str: string): Buffer32 {
- return new Buffer32(Buffer.from(str, 'hex'));
- }
-
- /**
- * Converts a string into a Buffer32 object.
- * NOTE: this method includes checks for the 0x prefix and the length of the string.
- * if you dont need this checks, use fromStringUnchecked instead.
- *
- * @param str - The TX hash in string format.
- * @returns A new Buffer32 object.
- */
public static fromString(str: string): Buffer32 {
if (str.startsWith('0x')) {
str = str.slice(2);
diff --git a/yarn-project/foundation/src/crypto/secp256k1-signer/secp256k1_signer.test.ts b/yarn-project/foundation/src/crypto/secp256k1-signer/secp256k1_signer.test.ts
index 707227208f2..05c9d12fdc7 100644
--- a/yarn-project/foundation/src/crypto/secp256k1-signer/secp256k1_signer.test.ts
+++ b/yarn-project/foundation/src/crypto/secp256k1-signer/secp256k1_signer.test.ts
@@ -31,13 +31,13 @@ describe('Secp256k1Signer', () => {
const ethHashedMessage = hashMessage({ raw: message });
const ethHashedMessageBuffer = Buffer32.fromBuffer(Buffer.from(ethHashedMessage.slice(2), 'hex'));
- const viemSignature = Signature.from0xString(await viemSigner.signMessage({ message: { raw: message } }));
+ const viemSignature = Signature.fromString(await viemSigner.signMessage({ message: { raw: message } }));
const lightSignature = lightSigner.sign(ethHashedMessageBuffer);
// Check signatures match
expect(viemSignature.equals(lightSignature)).toBe(true);
- const viemPublicKey = await viemRecoverPublicKey({ hash: ethHashedMessage, signature: viemSignature.to0xString() });
+ const viemPublicKey = await viemRecoverPublicKey({ hash: ethHashedMessage, signature: viemSignature.toString() });
const lightPublicKey = lightRecoverPublicKey(ethHashedMessageBuffer, lightSignature);
// Check recovered public keys match
@@ -46,7 +46,7 @@ describe('Secp256k1Signer', () => {
// Get the eth address can be recovered from the message and signature
const viemPublicKeyToAddress = publicKeyToAddress(viemPublicKey);
const viemAddress = EthAddress.fromString(
- await viemRecoverAddress({ hash: ethHashedMessage, signature: viemSignature.to0xString() }),
+ await viemRecoverAddress({ hash: ethHashedMessage, signature: viemSignature.toString() }),
);
const lightAddress = lightRecoverAddress(
Buffer32.fromBuffer(Buffer.from(ethHashedMessage.slice(2), 'hex')),
diff --git a/yarn-project/foundation/src/eth-address/index.ts b/yarn-project/foundation/src/eth-address/index.ts
index f30e61a0230..ed9acffbb5b 100644
--- a/yarn-project/foundation/src/eth-address/index.ts
+++ b/yarn-project/foundation/src/eth-address/index.ts
@@ -3,8 +3,10 @@ import { inspect } from 'util';
import { keccak256String } from '../crypto/keccak/index.js';
import { randomBytes } from '../crypto/random/index.js';
import { Fr } from '../fields/index.js';
+import { hexSchemaFor } from '../schemas/utils.js';
import { BufferReader, FieldReader } from '../serialize/index.js';
import { TypeRegistry } from '../serialize/type_registry.js';
+import { bufferToHex } from '../string/index.js';
/**
* Represents an Ethereum address as a 20-byte buffer and provides various utility methods
@@ -154,7 +156,7 @@ export class EthAddress {
* @returns A hex-encoded string representation of the Ethereum address.
*/
public toString() {
- return `0x${this.buffer.toString('hex')}` as `0x${string}`;
+ return bufferToHex(this.buffer);
}
[inspect.custom]() {
@@ -226,19 +228,12 @@ export class EthAddress {
return new EthAddress(reader.readBytes(EthAddress.SIZE_IN_BYTES));
}
- /**
- * Friendly representation for debugging purposes.
- * @returns A hex string representing the address.
- */
- toFriendlyJSON() {
+ toJSON() {
return this.toString();
}
- toJSON() {
- return {
- type: 'EthAddress',
- value: this.toString(),
- };
+ static get schema() {
+ return hexSchemaFor(EthAddress, EthAddress.isAddress);
}
}
diff --git a/yarn-project/foundation/src/eth-signature/eth_signature.test.ts b/yarn-project/foundation/src/eth-signature/eth_signature.test.ts
index 2a2fd690184..ec76be5b6fa 100644
--- a/yarn-project/foundation/src/eth-signature/eth_signature.test.ts
+++ b/yarn-project/foundation/src/eth-signature/eth_signature.test.ts
@@ -25,15 +25,15 @@ describe('eth signature', () => {
expect(deserialized).toEqual(serialized);
};
- it('should serialize / deserialize to buffer', () => {
+ it('should serialize and deserialize to buffer', () => {
const serialized = signature.toBuffer();
const deserialized = Signature.fromBuffer(serialized);
checkEquivalence(signature, deserialized);
});
- it('should serialize / deserialize real signature to hex string', () => {
- const serialized = signature.to0xString();
- const deserialized = Signature.from0xString(serialized);
+ it('should serialize and deserialize real signature to hex string', () => {
+ const serialized = signature.toString();
+ const deserialized = Signature.fromString(serialized);
checkEquivalence(signature, deserialized);
});
@@ -42,24 +42,24 @@ describe('eth signature', () => {
expect(sender).toEqual(signer.address);
});
- it('should serialize / deserialize to hex string with v=0', () => {
+ it('should serialize and deserialize to hex string with v=0', () => {
const signature = new Signature(Buffer32.random(), Buffer32.random(), 0, false);
- const serialized = signature.to0xString();
- const deserialized = Signature.from0xString(serialized);
+ const serialized = signature.toString();
+ const deserialized = Signature.fromString(serialized);
checkEquivalence(signature, deserialized);
});
- it('should serialize / deserialize to hex string with 1-digit v', () => {
+ it('should serialize and deserialize to hex string with 1-digit v', () => {
const signature = new Signature(Buffer32.random(), Buffer32.random(), 1, false);
- const serialized = signature.to0xString();
- const deserialized = Signature.from0xString(serialized);
+ const serialized = signature.toString();
+ const deserialized = Signature.fromString(serialized);
checkEquivalence(signature, deserialized);
});
- it('should serialize / deserialize to hex string with 2-digit v', () => {
+ it('should serialize and deserialize to hex string with 2-digit v', () => {
const signature = new Signature(Buffer32.random(), Buffer32.random(), 26, false);
- const serialized = signature.to0xString();
- const deserialized = Signature.from0xString(serialized);
+ const serialized = signature.toString();
+ const deserialized = Signature.fromString(serialized);
checkEquivalence(signature, deserialized);
});
});
diff --git a/yarn-project/foundation/src/eth-signature/eth_signature.ts b/yarn-project/foundation/src/eth-signature/eth_signature.ts
index 521cf680e9e..dec046702d0 100644
--- a/yarn-project/foundation/src/eth-signature/eth_signature.ts
+++ b/yarn-project/foundation/src/eth-signature/eth_signature.ts
@@ -1,6 +1,10 @@
import { Buffer32 } from '@aztec/foundation/buffer';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
+import { z } from 'zod';
+
+import { hasHexPrefix, hexToBuffer } from '../string/index.js';
+
/**Viem Signature
*
* A version of the Signature class that uses `0x${string}` values for r and s rather than
@@ -45,7 +49,7 @@ export class Signature {
return new Signature(r, s, v, isEmpty);
}
- static isValid0xString(sig: `0x${string}`): boolean {
+ static isValidString(sig: `0x${string}`): boolean {
return /^0x[0-9a-f]{129,}$/i.test(sig);
}
@@ -54,10 +58,9 @@ export class Signature {
* parsing from viem, we can expect the v value to be a u8, rather than our
* default serialization of u32
*/
- static from0xString(sig: `0x${string}`): Signature {
- const buf = Buffer.from(sig.slice(2), 'hex');
+ static fromString(sig: `0x${string}`): Signature {
+ const buf = hexToBuffer(sig);
const reader = BufferReader.asReader(buf);
-
const r = reader.readObject(Buffer32);
const s = reader.readObject(Buffer32);
const v = parseInt(sig.slice(2 + 64 * 2), 16);
@@ -95,8 +98,8 @@ export class Signature {
return this.size;
}
- to0xString(): `0x${string}` {
- return `0x${this.r.toString()}${this.s.toString()}${this.v.toString(16)}`;
+ toString(): `0x${string}` {
+ return `0x${this.r.buffer.toString('hex')}${this.s.buffer.toString('hex')}${this.v.toString(16)}`;
}
/**
@@ -104,14 +107,22 @@ export class Signature {
*/
toViemSignature(): ViemSignature {
return {
- r: this.r.to0xString(),
- s: this.s.to0xString(),
+ r: this.r.toString(),
+ s: this.s.toString(),
v: this.v,
isEmpty: this.isEmpty,
};
}
toJSON() {
- return this.to0xString();
+ return this.toString();
+ }
+
+ static get schema() {
+ return z
+ .string()
+ .refine(hasHexPrefix, 'No hex prefix')
+ .refine(Signature.isValidString, 'Not a valid Ethereum signature')
+ .transform(Signature.fromString);
}
}
diff --git a/yarn-project/foundation/src/fields/fields.ts b/yarn-project/foundation/src/fields/fields.ts
index 4653d0eeee8..84b559c4f3c 100644
--- a/yarn-project/foundation/src/fields/fields.ts
+++ b/yarn-project/foundation/src/fields/fields.ts
@@ -4,6 +4,7 @@ import { inspect } from 'util';
import { toBigIntBE, toBufferBE } from '../bigint-buffer/index.js';
import { randomBytes } from '../crypto/random/index.js';
+import { hexSchemaFor } from '../schemas/utils.js';
import { BufferReader } from '../serialize/buffer_reader.js';
import { TypeRegistry } from '../serialize/type_registry.js';
@@ -300,12 +301,12 @@ export class Fr extends BaseField {
return Fr.fromBuffer(rootBuf);
}
- // TODO(palla/schemas): Use toString instead of structured type
toJSON() {
- return {
- type: 'Fr',
- value: this.toString(),
- };
+ return this.toString();
+ }
+
+ static get schema() {
+ return hexSchemaFor(Fr);
}
}
@@ -385,10 +386,11 @@ export class Fq extends BaseField {
}
toJSON() {
- return {
- type: 'Fq',
- value: this.toString(),
- };
+ return this.toString();
+ }
+
+ static get schema() {
+ return hexSchemaFor(Fq);
}
}
diff --git a/yarn-project/foundation/src/fields/point.test.ts b/yarn-project/foundation/src/fields/point.test.ts
index f2b4813683a..f98771fb5c0 100644
--- a/yarn-project/foundation/src/fields/point.test.ts
+++ b/yarn-project/foundation/src/fields/point.test.ts
@@ -1,3 +1,4 @@
+import { jsonParseWithSchema, jsonStringify } from '../json-rpc/convert.js';
import { schemas } from '../schemas/schemas.js';
import { updateInlineTestData } from '../testing/test_data.js';
import { Fr } from './fields.js';
@@ -93,7 +94,7 @@ describe('Point', () => {
it('serializes from and to JSON', () => {
const p = Point.random();
- const p2 = schemas.Point.parse(JSON.parse(JSON.stringify(p)));
+ const p2 = jsonParseWithSchema(jsonStringify(p), schemas.Point);
expect(p).toEqual(p2);
expect(p2).toBeInstanceOf(Point);
});
diff --git a/yarn-project/foundation/src/fields/point.ts b/yarn-project/foundation/src/fields/point.ts
index bfe1adcb3e7..96135f47b50 100644
--- a/yarn-project/foundation/src/fields/point.ts
+++ b/yarn-project/foundation/src/fields/point.ts
@@ -1,7 +1,9 @@
import { toBigIntBE } from '../bigint-buffer/index.js';
import { poseidon2Hash } from '../crypto/poseidon/index.js';
import { randomBoolean } from '../crypto/random/index.js';
+import { hexSchemaFor } from '../schemas/utils.js';
import { BufferReader, FieldReader, serializeToBuffer } from '../serialize/index.js';
+import { bufferToHex, hexToBuffer } from '../string/index.js';
import { Fr } from './fields.js';
/**
@@ -34,6 +36,14 @@ export class Point {
// TODO(#7386): check if on curve
}
+ toJSON() {
+ return this.toString();
+ }
+
+ static get schema() {
+ return hexSchemaFor(Point);
+ }
+
/**
* Generate a random Point instance.
*
@@ -84,14 +94,14 @@ export class Point {
/**
* Create a Point instance from a hex-encoded string.
- * The input 'address' should be prefixed with '0x' or not, and have exactly 128 hex characters representing the x and y coordinates.
+ * The input should be prefixed with '0x' or not, and have exactly 128 hex characters representing the x and y coordinates.
* Throws an error if the input length is invalid or coordinate values are out of range.
*
- * @param address - The hex-encoded string representing the Point coordinates.
+ * @param str - The hex-encoded string representing the Point coordinates.
* @returns A Point instance.
*/
- static fromString(address: string) {
- return this.fromBuffer(Buffer.from(address.replace(/^0x/i, ''), 'hex'));
+ static fromString(str: string) {
+ return this.fromBuffer(hexToBuffer(str));
}
/**
@@ -211,7 +221,7 @@ export class Point {
* @returns A hex-encoded string representing the Point instance.
*/
toString() {
- return '0x' + this.toBuffer().toString('hex');
+ return bufferToHex(this.toBuffer());
}
/**
diff --git a/yarn-project/foundation/src/json-rpc/client/fetch.ts b/yarn-project/foundation/src/json-rpc/client/fetch.ts
index f93dce97f43..56773431b6d 100644
--- a/yarn-project/foundation/src/json-rpc/client/fetch.ts
+++ b/yarn-project/foundation/src/json-rpc/client/fetch.ts
@@ -1,4 +1,4 @@
-import { format } from 'util';
+import { format, inspect } from 'util';
import { type DebugLogger, createDebugLogger } from '../../log/index.js';
import { NoRetryError, makeBackoff, retry } from '../../retry/index.js';
@@ -25,18 +25,23 @@ export async function defaultFetch(
) {
log.debug(format(`JsonRpcClient.fetch`, host, rpcMethod, '->', body));
let resp: Response;
- if (useApiEndpoints) {
- resp = await fetch(`${host}/${rpcMethod}`, {
- method: 'POST',
- body: jsonStringify(body),
- headers: { 'content-type': 'application/json' },
- });
- } else {
- resp = await fetch(host, {
- method: 'POST',
- body: jsonStringify({ ...body, method: rpcMethod }),
- headers: { 'content-type': 'application/json' },
- });
+ try {
+ if (useApiEndpoints) {
+ resp = await fetch(`${host}/${rpcMethod}`, {
+ method: 'POST',
+ body: jsonStringify(body),
+ headers: { 'content-type': 'application/json' },
+ });
+ } else {
+ resp = await fetch(host, {
+ method: 'POST',
+ body: jsonStringify({ ...body, method: rpcMethod }),
+ headers: { 'content-type': 'application/json' },
+ });
+ }
+ } catch (err) {
+ const errorMessage = `Error fetching from host ${host} with method ${rpcMethod}: ${inspect(err)}`;
+ throw new Error(errorMessage);
}
let responseJson;
diff --git a/yarn-project/foundation/src/json-rpc/convert.test.ts b/yarn-project/foundation/src/json-rpc/convert.test.ts
index b0817f765d4..98f06a0fb70 100644
--- a/yarn-project/foundation/src/json-rpc/convert.test.ts
+++ b/yarn-project/foundation/src/json-rpc/convert.test.ts
@@ -1,5 +1,6 @@
import { type ZodTypeAny, z } from 'zod';
+import { schemas } from '../schemas/schemas.js';
import { mapSchema, setSchema } from '../schemas/utils.js';
import { jsonStringify } from './convert.js';
@@ -9,27 +10,27 @@ describe('jsonStringify', () => {
expect(schema.parse(JSON.parse(json))).toEqual(value);
};
- it('object with primitive types', () => {
+ it('handles object with primitive types', () => {
const values = { a: 10, b: 'foo', c: true };
test(values, z.object({ a: z.number(), b: z.string(), c: z.boolean() }));
});
- it('object with bigints', () => {
+ it('handles object with bigints', () => {
const values = { a: 10n };
test(values, z.object({ a: z.coerce.bigint() }));
});
- it('tuples', () => {
+ it('handles tuples', () => {
const values = [10, 'foo', true];
test(values, z.tuple([z.number(), z.string(), z.boolean()]));
});
- it('arrays', () => {
+ it('handles arrays', () => {
const values = [10, 20, 30];
test(values, z.array(z.number()));
});
- it('maps', () => {
+ it('handles maps', () => {
const values = new Map([
['a', 10],
['b', 20],
@@ -37,8 +38,21 @@ describe('jsonStringify', () => {
test(values, mapSchema(z.string(), z.number()));
});
- it('sets', () => {
+ it('handles sets', () => {
const values = new Set([10, 20]);
test(values, setSchema(z.number()));
});
+
+ it('handles buffers', () => {
+ const value = Buffer.from('hello');
+ const json = jsonStringify(value);
+ expect(json).toEqual('"aGVsbG8="');
+ test(value, schemas.Buffer);
+ });
+
+ it('handles nullish', () => {
+ const values = [null, undefined];
+ const json = jsonStringify(values);
+ expect(JSON.parse(json)).toEqual([null, null]);
+ });
});
diff --git a/yarn-project/foundation/src/json-rpc/convert.ts b/yarn-project/foundation/src/json-rpc/convert.ts
index 8b040d74483..c518b3faa36 100644
--- a/yarn-project/foundation/src/json-rpc/convert.ts
+++ b/yarn-project/foundation/src/json-rpc/convert.ts
@@ -23,7 +23,9 @@ export function jsonStringify(obj: object, prettify?: boolean): string {
(_key, value) => {
if (typeof value === 'bigint') {
return value.toString();
- } else if (typeof value === 'object' && Buffer.isBuffer(value)) {
+ } else if (typeof value === 'object' && value && value.type === 'Buffer' && Array.isArray(value.data)) {
+ return Buffer.from(value.data).toString('base64');
+ } else if (typeof value === 'object' && value && Buffer.isBuffer(value)) {
return value.toString('base64');
} else if (typeof value === 'object' && value instanceof Map) {
return Array.from(value.entries());
diff --git a/yarn-project/foundation/src/json-rpc/index.ts b/yarn-project/foundation/src/json-rpc/index.ts
index 2e33ff54f4e..8b918b16c74 100644
--- a/yarn-project/foundation/src/json-rpc/index.ts
+++ b/yarn-project/foundation/src/json-rpc/index.ts
@@ -1 +1 @@
-export { jsonStringify } from './convert.js';
+export { jsonStringify, jsonParseWithSchema, tryJsonStringify } from './convert.js';
diff --git a/yarn-project/foundation/src/schemas/schemas.ts b/yarn-project/foundation/src/schemas/schemas.ts
index eca83d8bcd0..5677274d59c 100644
--- a/yarn-project/foundation/src/schemas/schemas.ts
+++ b/yarn-project/foundation/src/schemas/schemas.ts
@@ -7,65 +7,45 @@ import { NoteSelector } from '../abi/note_selector.js';
import { AztecAddress } from '../aztec-address/index.js';
import { Buffer32 } from '../buffer/buffer32.js';
import { EthAddress } from '../eth-address/index.js';
-import { Signature } from '../eth-signature/eth_signature.js';
import { Fq, Fr } from '../fields/fields.js';
import { Point } from '../fields/point.js';
-import { hasHexPrefix, isHex, withoutHexPrefix } from '../string/index.js';
+import { isHex, withoutHexPrefix } from '../string/index.js';
import { type ZodFor } from './types.js';
-import { hexSchema, maybeStructuredStringSchemaFor } from './utils.js';
-
-const FrSchema = maybeStructuredStringSchemaFor('Fr', Fr, isHex);
-const FqSchema = maybeStructuredStringSchemaFor('Fq', Fq, isHex);
+import { bufferSchema, hexSchema } from './utils.js';
/** Validation schemas for common types. Every schema must match its toJSON. */
export const schemas = {
- /** Accepts both a 0x string and a structured `{ type: EthAddress, value: '0x...' }` */
- EthAddress: maybeStructuredStringSchemaFor('EthAddress', EthAddress, EthAddress.isAddress),
-
- /** Accepts both a 0x string and a structured `{ type: AztecAddress, value: '0x...' }` */
- AztecAddress: maybeStructuredStringSchemaFor('AztecAddress', AztecAddress, AztecAddress.isAddress),
+ /** Accepts a hex string. */
+ EthAddress: EthAddress.schema,
- /** Accepts both a 0x string and a structured type. */
- FunctionSelector: maybeStructuredStringSchemaFor('FunctionSelector', FunctionSelector),
+ /** Accepts a hex string. */
+ AztecAddress: AztecAddress.schema,
- /** Accepts both a 0x string and a structured type. */
- NoteSelector: maybeStructuredStringSchemaFor('NoteSelector', NoteSelector),
+ /** Accepts a hex string. */
+ FunctionSelector: FunctionSelector.schema,
- /** Accepts both a 0x string and a structured type. */
- EventSelector: maybeStructuredStringSchemaFor('EventSelector', EventSelector),
+ /** Accepts a hex string. */
+ NoteSelector: NoteSelector.schema,
- /** Field element. Accepts a 0x prefixed hex string or a structured type. */
- Fr: FrSchema,
+ /** Accepts a hex string. */
+ EventSelector: EventSelector.schema,
- /** Field element. Accepts a 0x prefixed hex string or a structured type. */
- Fq: FqSchema,
+ /** Accepts a hex string. */
+ Fr: Fr.schema,
- /** Point. Serialized as 0x prefixed string or a type. */
- Point: z
- .object({
- x: FrSchema,
- y: FrSchema,
- isInfinite: z.boolean().optional(),
- })
- .or(hexSchema)
- .transform(value =>
- typeof value === 'string' ? Point.fromString(value) : new Point(value.x, value.y, value.isInfinite ?? false),
- ),
+ /** Accepts a hex string. */
+ Fq: Fq.schema,
- /** Accepts a 0x string */
- Signature: z
- .string()
- .refine(hasHexPrefix, 'No hex prefix')
- .refine(Signature.isValid0xString, 'Not a valid Ethereum signature')
- .transform(Signature.from0xString),
+ /** Point. Serialized as a hex string. */
+ Point: Point.schema,
- /** Coerces any input to bigint */
+ /** Coerces any input to bigint. */
BigInt: z.union([z.bigint(), z.number(), z.string()]).pipe(z.coerce.bigint()),
- /** Coerces any input to integer number */
+ /** Coerces any input to integer number. */
Integer: z.union([z.bigint(), z.number(), z.string()]).pipe(z.coerce.number().int()),
- /** Coerces input to UInt32 */
+ /** Coerces input to UInt32. */
UInt32: z.union([z.bigint(), z.number(), z.string()]).pipe(
z.coerce
.number()
@@ -74,31 +54,28 @@ export const schemas = {
.max(2 ** 32 - 1),
),
- /** Accepts a hex string as a Buffer32 type */
+ /** Accepts a hex string as a Buffer32 type. */
Buffer32: z.string().refine(isHex, 'Not a valid hex string').transform(Buffer32.fromString),
- /** Accepts a base64 string or a structured `{ type: 'Buffer', data: [byte, byte...] }` as a buffer */
- BufferB64: z.union([
- z
- .string()
- .base64()
- .transform(data => Buffer.from(data, 'base64')),
+ /** Accepts a base64 string or an object `{ type: 'Buffer', data: [byte, byte...] }` as a buffer. */
+ Buffer: z.union([
+ bufferSchema,
z
.object({
type: z.literal('Buffer'),
- data: z.array(z.number().int().max(255)),
+ data: z.array(z.number().int().min(0).max(255)),
})
.transform(({ data }) => Buffer.from(data)),
]),
- /** Accepts a hex string with optional 0x prefix as a buffer */
+ /** Accepts a hex string as a buffer. */
BufferHex: z
.string()
.refine(isHex, 'Not a valid hex string')
.transform(withoutHexPrefix)
.transform(data => Buffer.from(data, 'hex')),
- /** Hex string with an optional 0x prefix, which gets removed as part of the parsing */
+ /** Hex string with an optional 0x prefix which gets removed as part of the parsing. */
HexString: hexSchema,
};
diff --git a/yarn-project/foundation/src/schemas/utils.ts b/yarn-project/foundation/src/schemas/utils.ts
index 412c49bc967..5e12c46848b 100644
--- a/yarn-project/foundation/src/schemas/utils.ts
+++ b/yarn-project/foundation/src/schemas/utils.ts
@@ -15,6 +15,17 @@ import { type ZodFor } from './types.js';
export const hexSchema = z.string().refine(isHex, 'Not a valid hex string').transform(withoutHexPrefix);
+// Copied from zod internals, which was copied from https://stackoverflow.com/questions/7860392/determine-if-string-is-in-base64-using-javascript
+const base64Regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;
+
+/** Schema for a buffer represented as a base64 string. */
+export const bufferSchema = z
+ .string()
+ // We only test the str for base64 if it's shorter than 1024 bytes, otherwise we've run into maximum
+ // stack size exceeded errors when trying to validate excessively long strings (such as contract bytecode).
+ .refine(str => str.length > 1024 || base64Regex.test(str), 'Not a valid base64 string')
+ .transform(data => Buffer.from(data, 'base64'));
+
export class ZodNullableOptional extends ZodOptional {
_isNullableOptional = true;
@@ -43,6 +54,8 @@ export function optional(schema: T) {
return ZodNullableOptional.create(schema);
}
+type ToJsonIs = T extends { toJSON(): TRet } ? T : never;
+
/**
* Creates a schema that accepts a hex string and uses it to hydrate an instance.
* @param klazz - Class that implements either fromString or fromBuffer.
@@ -50,28 +63,34 @@ export function optional(schema: T) {
*/
export function hexSchemaFor(
klazz: TClass,
+ refinement?: (input: string) => boolean,
): ZodType<
TClass extends { fromString(str: string): infer TInstance } | { fromBuffer(buf: Buffer): infer TInstance }
- ? TInstance
+ ? ToJsonIs
: never,
any,
string
> {
+ const stringSchema = refinement ? z.string().refine(refinement, `Not a valid instance`) : z.string();
+ const hexSchema = stringSchema.refine(isHex, 'Not a valid hex string').transform(withoutHexPrefix);
return 'fromString' in klazz
? hexSchema.transform(klazz.fromString.bind(klazz))
: hexSchema.transform(str => Buffer.from(str, 'hex')).transform(klazz.fromBuffer.bind(klazz));
}
-// TODO(palla/schemas): Delete this class once all serialization of the type { type: string, value: string } are removed.
-export function maybeStructuredStringSchemaFor(
- name: string,
+/**
+ * Creates a schema that accepts a base64 string and uses it to hydrate an instance.
+ * @param klazz - Class that implements fromBuffer.
+ * @returns A schema for the class.
+ */
+export function bufferSchemaFor(
klazz: TClass,
- refinement?: (input: string) => boolean,
-): ZodFor {
- const stringSchema = refinement ? z.string().refine(refinement, `Not a valid ${name}`) : z.string();
- return z
- .union([stringSchema, z.object({ type: z.literal(name), value: stringSchema })])
- .transform(input => klazz.fromString(typeof input === 'string' ? input : input.value));
+): ZodType<
+ TClass extends { fromBuffer(buf: Buffer): infer TInstance } ? ToJsonIs : never,
+ any,
+ string
+> {
+ return bufferSchema.transform(klazz.fromBuffer.bind(klazz));
}
/** Creates a schema for a js Map type that matches the serialization used in jsonStringify. */
diff --git a/yarn-project/foundation/src/serialize/type_registry.test.ts b/yarn-project/foundation/src/serialize/type_registry.test.ts
new file mode 100644
index 00000000000..b77e96a837f
--- /dev/null
+++ b/yarn-project/foundation/src/serialize/type_registry.test.ts
@@ -0,0 +1,90 @@
+import { EventSelector } from '../abi/event_selector.js';
+import { FunctionSelector } from '../abi/function_selector.js';
+import { NoteSelector } from '../abi/note_selector.js';
+import { AztecAddress } from '../aztec-address/index.js';
+import { EthAddress } from '../eth-address/index.js';
+import { Fq, Fr } from '../fields/fields.js';
+import { resolver, reviver } from './type_registry.js';
+
+describe('TypeRegistry', () => {
+ it('serializes registered type with type info', () => {
+ const data = { fr: Fr.random() };
+ const json = JSON.stringify(data, resolver);
+ const parsed = JSON.parse(json);
+ expect(parsed.fr).toEqual({ type: 'Fr', value: data.fr.toString() });
+ });
+
+ it('deserializes registered types in objects', () => {
+ const data = {
+ fr: Fr.random(),
+ fq: Fq.random(),
+ aztecAddress: AztecAddress.random(),
+ ethAddress: EthAddress.random(),
+ functionSelector: FunctionSelector.random(),
+ noteSelector: NoteSelector.random(),
+ };
+
+ const json = JSON.stringify(data, resolver);
+ const parsed = JSON.parse(json, reviver);
+
+ expect(parsed).toEqual(data);
+ expect(parsed.fr).toBeInstanceOf(Fr);
+ expect(parsed.fq).toBeInstanceOf(Fq);
+ expect(parsed.aztecAddress).toBeInstanceOf(AztecAddress);
+ expect(parsed.ethAddress).toBeInstanceOf(EthAddress);
+ expect(parsed.functionSelector).toBeInstanceOf(FunctionSelector);
+ expect(parsed.noteSelector).toBeInstanceOf(NoteSelector);
+ });
+
+ it('deserializes registered types in arrays', () => {
+ const data = [
+ Fr.random(),
+ Fq.random(),
+ AztecAddress.random(),
+ EthAddress.random(),
+ FunctionSelector.random(),
+ NoteSelector.random(),
+ ];
+
+ const json = JSON.stringify(data, resolver);
+ const parsed = JSON.parse(json, reviver);
+
+ expect(parsed).toEqual(data);
+ expect(parsed[0]).toBeInstanceOf(Fr);
+ expect(parsed[1]).toBeInstanceOf(Fq);
+ expect(parsed[2]).toBeInstanceOf(AztecAddress);
+ expect(parsed[3]).toBeInstanceOf(EthAddress);
+ expect(parsed[4]).toBeInstanceOf(FunctionSelector);
+ expect(parsed[5]).toBeInstanceOf(NoteSelector);
+ });
+
+ it('ignores unregistered types', () => {
+ const data = { eventSelector: EventSelector.random() };
+ const json = JSON.stringify(data, resolver);
+ const parsed = JSON.parse(json);
+ expect(parsed.eventSelector).toEqual(data.eventSelector.toString());
+ });
+
+ it('handles plain objects', () => {
+ const data = { obj: { number: 10, string: 'string', fr: Fr.random() } };
+ const json = JSON.stringify(data, resolver);
+ const parsed = JSON.parse(json, reviver);
+ expect(parsed).toEqual(data);
+ expect(parsed.obj.fr).toBeInstanceOf(Fr);
+ });
+
+ it('handles plain arrays', () => {
+ const data = [10, 'string', Fr.random()];
+ const json = JSON.stringify(data, resolver);
+ const parsed = JSON.parse(json, reviver);
+ expect(parsed).toEqual(data);
+ expect(parsed[2]).toBeInstanceOf(Fr);
+ });
+
+ it('handles bigints', () => {
+ const data = { bigInt: BigInt(10) };
+ const json = JSON.stringify(data, resolver);
+ const parsed = JSON.parse(json, reviver);
+ expect(parsed.bigInt).toEqual(BigInt(10));
+ });
+});
diff --git a/yarn-project/foundation/src/serialize/type_registry.ts b/yarn-project/foundation/src/serialize/type_registry.ts
index 85146710ed8..39a6bd00ad3 100644
--- a/yarn-project/foundation/src/serialize/type_registry.ts
+++ b/yarn-project/foundation/src/serialize/type_registry.ts
@@ -1,3 +1,5 @@
+import { mapValues } from '../collection/object.js';
+
type Deserializable = { fromString(str: string): object };
/**
@@ -23,9 +25,39 @@ export class TypeRegistry {
}
}
+function replace(value: T) {
+ if (
+ value &&
+ typeof value === 'object' &&
+ 'toString' in value &&
+ TypeRegistry.getConstructor(value.constructor.name)
+ ) {
+ return {
+ type: value.constructor.name,
+ value: value.toString(),
+ };
+ }
+
+ return value;
+}
+
// Resolver function that enables JSON serialization of BigInts.
export function resolver(_: any, value: any) {
- return typeof value === 'bigint' ? value.toString() + 'n' : value;
+ if (typeof value === 'bigint') {
+ return value.toString() + 'n';
+ }
+
+ if (typeof value === 'object' && value) {
+ if (Array.isArray(value)) {
+ return value.map(replace);
+ } else if (Buffer.isBuffer(value)) {
+ return { type: 'buffer', value: value.toString('hex') };
+ } else {
+ return mapValues(value, replace);
+ }
+ }
+
+ return value;
}
// Reviver function that uses TypeRegistry to instantiate objects.
diff --git a/yarn-project/foundation/src/string/index.ts b/yarn-project/foundation/src/string/index.ts
index 250b3c02581..1b85173fc1a 100644
--- a/yarn-project/foundation/src/string/index.ts
+++ b/yarn-project/foundation/src/string/index.ts
@@ -14,6 +14,10 @@ export function hexToBuffer(str: string): Buffer {
return Buffer.from(withoutHexPrefix(str), 'hex');
}
+export function bufferToHex(buffer: Buffer): `0x${string}` {
+ return `0x${buffer.toString('hex')}`;
+}
+
export function pluralize(str: string, count: number | bigint, plural?: string): string {
return count === 1 || count === 1n ? str : plural ?? `${str}s`;
}
diff --git a/yarn-project/noir-protocol-circuits-types/src/__snapshots__/noir_test_gen.test.ts.snap b/yarn-project/noir-protocol-circuits-types/src/__snapshots__/noir_test_gen.test.ts.snap
index c5b038f46bb..af7128a8549 100644
--- a/yarn-project/noir-protocol-circuits-types/src/__snapshots__/noir_test_gen.test.ts.snap
+++ b/yarn-project/noir-protocol-circuits-types/src/__snapshots__/noir_test_gen.test.ts.snap
@@ -9,7 +9,7 @@ exports[`Data generation for noir tests Computes contract info for defaultContra
address: AztecAddress { inner: 0x29bc2e90ff6ec5f4a7c7f502e368af01eb74131a2eec6320e0e45419cddc7b6d },
partial_address: PartialAddress { inner: 0x1a68423cf4f04eaede2b0e93131916b8b7330dae6e8ee202679d12a4eb49cc0b },
contract_class_id: ContractClassId { inner: 0x1195b865ef122d75c8c4d6102d536193b69bbb712c85bafcbf7694f52e2d8c36 },
- public_keys: PublicKeys { inner: 01498945581e0eb9f8427ad6021184c700ef091d570892c437d12c7d90364bbd170ae506787c5c43d6ca9255d571c10fa9ffa9d141666e290c347c5c9ab7e34400c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb1511b00316144359e9a3ec8e49c1cdb7eeb0cedd190dfd9dc90eea5115aa779e287080ffc74d7a8b0bccb88ac11f45874172f3847eb8b92654aaa58a3d2b8dc7833019c111f36ad3fc1d9b7a7a14344314d2864b94f030594cd67f753ef774a1efb2039907fe37f08d10739255141bb066c506a12f7d1e8dfec21abc58494705b6f },
+ public_keys: PublicKeys { inner: 0x01498945581e0eb9f8427ad6021184c700ef091d570892c437d12c7d90364bbd170ae506787c5c43d6ca9255d571c10fa9ffa9d141666e290c347c5c9ab7e34400c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb1511b00316144359e9a3ec8e49c1cdb7eeb0cedd190dfd9dc90eea5115aa779e287080ffc74d7a8b0bccb88ac11f45874172f3847eb8b92654aaa58a3d2b8dc7833019c111f36ad3fc1d9b7a7a14344314d2864b94f030594cd67f753ef774a1efb2039907fe37f08d10739255141bb066c506a12f7d1e8dfec21abc58494705b6f },
salted_initialization_hash: SaltedInitializationHash { inner: 0x13a939daa511233e5446905ed2cadbee14948fa75df183b53b5c14b612bffe88 },
deployer: AztecAddress { inner: 0x0000000000000000000000000000000000000000000000000000000000000000 }
}"
@@ -24,7 +24,7 @@ exports[`Data generation for noir tests Computes contract info for parentContrac
address: AztecAddress { inner: 0x2749b685f752f6dfe1d4e532fc036839004926b7c18abf1a4f69ddf97d62f40e },
partial_address: PartialAddress { inner: 0x1c30ee02dcd41bcdfc5191dc36ccaae15cdc7e1fc6bd8a0cbe1baeaf1335a771 },
contract_class_id: ContractClassId { inner: 0x24f1b8df215c10ee7edd213b439c8f8e99198a802a3e1e41597b6554b17049a3 },
- public_keys: PublicKeys { inner: 01498945581e0eb9f8427ad6021184c700ef091d570892c437d12c7d90364bbd170ae506787c5c43d6ca9255d571c10fa9ffa9d141666e290c347c5c9ab7e34400c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb1511b00316144359e9a3ec8e49c1cdb7eeb0cedd190dfd9dc90eea5115aa779e287080ffc74d7a8b0bccb88ac11f45874172f3847eb8b92654aaa58a3d2b8dc7833019c111f36ad3fc1d9b7a7a14344314d2864b94f030594cd67f753ef774a1efb2039907fe37f08d10739255141bb066c506a12f7d1e8dfec21abc58494705b6f },
+ public_keys: PublicKeys { inner: 0x01498945581e0eb9f8427ad6021184c700ef091d570892c437d12c7d90364bbd170ae506787c5c43d6ca9255d571c10fa9ffa9d141666e290c347c5c9ab7e34400c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb1511b00316144359e9a3ec8e49c1cdb7eeb0cedd190dfd9dc90eea5115aa779e287080ffc74d7a8b0bccb88ac11f45874172f3847eb8b92654aaa58a3d2b8dc7833019c111f36ad3fc1d9b7a7a14344314d2864b94f030594cd67f753ef774a1efb2039907fe37f08d10739255141bb066c506a12f7d1e8dfec21abc58494705b6f },
salted_initialization_hash: SaltedInitializationHash { inner: 0x24bd6ac7a182e2cf25e437c72f53544ef81dfd97d9afee23abb07a638e7be749 },
deployer: AztecAddress { inner: 0x0000000000000000000000000000000000000000000000000000000000000000 }
}"
diff --git a/yarn-project/prover-client/src/proving_broker/proving_job_database/persisted.ts b/yarn-project/prover-client/src/proving_broker/proving_job_database/persisted.ts
index 748ad387124..c03684b1bf3 100644
--- a/yarn-project/prover-client/src/proving_broker/proving_job_database/persisted.ts
+++ b/yarn-project/prover-client/src/proving_broker/proving_job_database/persisted.ts
@@ -1,4 +1,5 @@
import { type V2ProofOutput, V2ProvingJob, type V2ProvingJobId, V2ProvingJobResult } from '@aztec/circuit-types';
+import { jsonParseWithSchema, jsonStringify } from '@aztec/foundation/json-rpc';
import { type AztecKVStore, type AztecMap } from '@aztec/kv-store';
import { type ProvingJobDatabase } from '../proving_job_database.js';
@@ -13,14 +14,14 @@ export class PersistedProvingJobDatabase implements ProvingJobDatabase {
}
async addProvingJob(job: V2ProvingJob): Promise {
- await this.jobs.set(job.id, JSON.stringify(job));
+ await this.jobs.set(job.id, jsonStringify(job));
}
*allProvingJobs(): Iterable<[V2ProvingJob, V2ProvingJobResult | undefined]> {
for (const jobStr of this.jobs.values()) {
- const job = V2ProvingJob.parse(JSON.parse(jobStr));
+ const job = jsonParseWithSchema(jobStr, V2ProvingJob);
const resultStr = this.jobResults.get(job.id);
- const result = resultStr ? V2ProvingJobResult.parse(JSON.parse(resultStr)) : undefined;
+ const result = resultStr ? jsonParseWithSchema(resultStr, V2ProvingJobResult) : undefined;
yield [job, result];
}
}
@@ -34,11 +35,11 @@ export class PersistedProvingJobDatabase implements ProvingJobDatabase {
async setProvingJobError(id: V2ProvingJobId, err: Error): Promise {
const res: V2ProvingJobResult = { error: err.message };
- await this.jobResults.set(id, JSON.stringify(res));
+ await this.jobResults.set(id, jsonStringify(res));
}
async setProvingJobResult(id: V2ProvingJobId, value: V2ProofOutput): Promise {
const res: V2ProvingJobResult = { value };
- await this.jobResults.set(id, JSON.stringify(res));
+ await this.jobResults.set(id, jsonStringify(res));
}
}
diff --git a/yarn-project/prover-node/src/quote-provider/http.ts b/yarn-project/prover-node/src/quote-provider/http.ts
index 2e3a6ce6798..a50318143e9 100644
--- a/yarn-project/prover-node/src/quote-provider/http.ts
+++ b/yarn-project/prover-node/src/quote-provider/http.ts
@@ -1,4 +1,5 @@
import { type L2Block } from '@aztec/circuit-types';
+import { jsonStringify } from '@aztec/foundation/json-rpc';
import { type QuoteProvider, type QuoteProviderResult } from './index.js';
import { getTotalFees, getTxCount } from './utils.js';
@@ -17,7 +18,7 @@ export class HttpQuoteProvider implements QuoteProvider {
const response = await fetch(this.url, {
method: 'POST',
- body: JSON.stringify(payload),
+ body: jsonStringify(payload),
headers: { 'content-type': 'application/json' },
});
@@ -27,7 +28,7 @@ export class HttpQuoteProvider implements QuoteProvider {
const data = await response.json();
if (!data.basisPointFee || !data.bondAmount) {
- throw new Error(`Missing required fields (basisPointFee | bondAmount) in response: ${JSON.stringify(data)}`);
+ throw new Error(`Missing required fields (basisPointFee | bondAmount) in response: ${jsonStringify(data)}`);
}
const basisPointFee = Number(data.basisPointFee);
diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts
index a7ca08660f2..00dfea9c56d 100644
--- a/yarn-project/pxe/src/simulator_oracle/index.ts
+++ b/yarn-project/pxe/src/simulator_oracle/index.ts
@@ -27,6 +27,7 @@ import {
} from '@aztec/circuits.js';
import { type FunctionArtifact, getFunctionArtifact } from '@aztec/foundation/abi';
import { poseidon2Hash } from '@aztec/foundation/crypto';
+import { tryJsonStringify } from '@aztec/foundation/json-rpc';
import { createDebugLogger } from '@aztec/foundation/log';
import { type KeyStore } from '@aztec/key-store';
import { type AcirSimulator, type DBOracle, MessageLoadOracleInputs } from '@aztec/simulator';
@@ -556,9 +557,9 @@ export class SimulatorOracle implements DBOracle {
if (incomingNotePayload || outgoingNotePayload) {
if (incomingNotePayload && outgoingNotePayload && !incomingNotePayload.equals(outgoingNotePayload)) {
this.log.warn(
- `Incoming and outgoing note payloads do not match. Incoming: ${JSON.stringify(
+ `Incoming and outgoing note payloads do not match. Incoming: ${tryJsonStringify(
incomingNotePayload,
- )}, Outgoing: ${JSON.stringify(outgoingNotePayload)}`,
+ )}, Outgoing: ${tryJsonStringify(outgoingNotePayload)}`,
);
continue;
}
diff --git a/yarn-project/sequencer-client/src/block_builder/light.ts b/yarn-project/sequencer-client/src/block_builder/light.ts
index 44d92ca2a23..35ac23d476a 100644
--- a/yarn-project/sequencer-client/src/block_builder/light.ts
+++ b/yarn-project/sequencer-client/src/block_builder/light.ts
@@ -17,6 +17,8 @@ import { buildBaseRollupHints, buildHeaderFromTxEffects, getTreeSnapshot } from
import { type TelemetryClient } from '@aztec/telemetry-client';
import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
+import { inspect } from 'util';
+
/**
* Builds a block and its header from a set of processed tx without running any circuits.
*/
@@ -32,7 +34,7 @@ export class LightweightBlockBuilder implements BlockBuilder {
constructor(private db: MerkleTreeWriteOperations, private telemetry: TelemetryClient) {}
async startNewBlock(numTxs: number, globalVariables: GlobalVariables, l1ToL2Messages: Fr[]): Promise {
- this.logger.verbose('Starting new block', { numTxs, globalVariables: globalVariables.toJSON(), l1ToL2Messages });
+ this.logger.verbose('Starting new block', { numTxs, globalVariables: inspect(globalVariables), l1ToL2Messages });
this.numTxs = numTxs;
this.globalVariables = globalVariables;
this.l1ToL2Messages = padArrayEnd(l1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
diff --git a/yarn-project/sequencer-client/src/global_variable_builder/global_builder.ts b/yarn-project/sequencer-client/src/global_variable_builder/global_builder.ts
index adb1cb4f9e5..3ca0a790c77 100644
--- a/yarn-project/sequencer-client/src/global_variable_builder/global_builder.ts
+++ b/yarn-project/sequencer-client/src/global_variable_builder/global_builder.ts
@@ -89,7 +89,7 @@ export class GlobalVariableBuilder implements GlobalVariableBuilderInterface {
feeRecipient,
gasFees,
);
- this.log.debug(`Built global variables for block ${blockNumber}`, globalVariables.toJSON());
+ this.log.debug(`Built global variables for block ${blockNumber}`, globalVariables.toFriendlyJSON());
return globalVariables;
}
}
diff --git a/yarn-project/sequencer-client/src/publisher/l1-publisher.ts b/yarn-project/sequencer-client/src/publisher/l1-publisher.ts
index 29b4c8d1de3..2bc6c67d9b8 100644
--- a/yarn-project/sequencer-client/src/publisher/l1-publisher.ts
+++ b/yarn-project/sequencer-client/src/publisher/l1-publisher.ts
@@ -738,7 +738,7 @@ export class L1Publisher {
const attestations = encodedData.attestations
? encodedData.attestations.map(attest => attest.toViemSignature())
: [];
- const txHashes = encodedData.txHashes ? encodedData.txHashes.map(txHash => txHash.to0xString()) : [];
+ const txHashes = encodedData.txHashes ? encodedData.txHashes.map(txHash => txHash.toString()) : [];
const args = [
{
header: `0x${encodedData.header.toString('hex')}`,
diff --git a/yarn-project/simulator/src/avm/journal/journal.ts b/yarn-project/simulator/src/avm/journal/journal.ts
index f89d4c94f90..90bb0e75b89 100644
--- a/yarn-project/simulator/src/avm/journal/journal.ts
+++ b/yarn-project/simulator/src/avm/journal/journal.ts
@@ -9,6 +9,7 @@ import {
} from '@aztec/circuits.js';
import { computePublicDataTreeLeafSlot, siloNoteHash, siloNullifier } from '@aztec/circuits.js/hash';
import { Fr } from '@aztec/foundation/fields';
+import { jsonStringify } from '@aztec/foundation/json-rpc';
import { createDebugLogger } from '@aztec/foundation/log';
import assert from 'assert';
@@ -468,7 +469,7 @@ export class AvmPersistableStateManager {
if (exists) {
const instance = new SerializableContractInstance(instanceWithAddress);
this.log.debug(
- `Got contract instance (address=${contractAddress}): exists=${exists}, instance=${JSON.stringify(instance)}`,
+ `Got contract instance (address=${contractAddress}): exists=${exists}, instance=${jsonStringify(instance)}`,
);
this.trace.traceGetContractInstance(contractAddress, exists, instance);
diff --git a/yarn-project/simulator/src/common/errors.ts b/yarn-project/simulator/src/common/errors.ts
index f51536ac457..da35b96d784 100644
--- a/yarn-project/simulator/src/common/errors.ts
+++ b/yarn-project/simulator/src/common/errors.ts
@@ -6,6 +6,7 @@ import {
} from '@aztec/circuit-types';
import { type Fr } from '@aztec/circuits.js';
import type { BrilligFunctionId, FunctionAbi, FunctionDebugMetadata, OpcodeLocation } from '@aztec/foundation/abi';
+import { jsonStringify } from '@aztec/foundation/json-rpc';
import { type RawAssertionPayload } from '@noir-lang/acvm_js';
import { abiDecodeError } from '@noir-lang/noirc_abi';
@@ -153,7 +154,7 @@ export function resolveAssertionMessage(errorPayload: RawAssertionPayload, abi:
if (typeof decoded === 'string') {
return decoded;
} else {
- return JSON.stringify(decoded);
+ return jsonStringify(decoded);
}
}
diff --git a/yarn-project/simulator/src/public/enqueued_call_side_effect_trace.ts b/yarn-project/simulator/src/public/enqueued_call_side_effect_trace.ts
index 768243bf473..41298d80f63 100644
--- a/yarn-project/simulator/src/public/enqueued_call_side_effect_trace.ts
+++ b/yarn-project/simulator/src/public/enqueued_call_side_effect_trace.ts
@@ -58,6 +58,7 @@ import {
import { computePublicDataTreeLeafSlot, siloNullifier } from '@aztec/circuits.js/hash';
import { padArrayEnd } from '@aztec/foundation/collection';
import { Fr } from '@aztec/foundation/fields';
+import { jsonStringify } from '@aztec/foundation/json-rpc';
import { createDebugLogger } from '@aztec/foundation/log';
import { assert } from 'console';
@@ -495,9 +496,7 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI
new AvmContractBytecodeHints(bytecode, instance, contractClass),
);
this.log.debug(
- `Bytecode retrieval for contract execution traced: exists=${exists}, instance=${JSON.stringify(
- contractInstance,
- )}`,
+ `Bytecode retrieval for contract execution traced: exists=${exists}, instance=${jsonStringify(contractInstance)}`,
);
}
diff --git a/yarn-project/simulator/src/public/side_effect_trace.ts b/yarn-project/simulator/src/public/side_effect_trace.ts
index ac1f4a98f16..dcb86a1850d 100644
--- a/yarn-project/simulator/src/public/side_effect_trace.ts
+++ b/yarn-project/simulator/src/public/side_effect_trace.ts
@@ -45,6 +45,7 @@ import {
TreeLeafReadRequest,
} from '@aztec/circuits.js';
import { Fr } from '@aztec/foundation/fields';
+import { jsonStringify } from '@aztec/foundation/json-rpc';
import { createDebugLogger } from '@aztec/foundation/log';
import { assert } from 'console';
@@ -362,9 +363,7 @@ export class PublicSideEffectTrace implements PublicSideEffectTraceInterface {
new AvmContractBytecodeHints(bytecode, instance, contractClass),
);
this.log.debug(
- `Bytecode retrieval for contract execution traced: exists=${exists}, instance=${JSON.stringify(
- contractInstance,
- )}`,
+ `Bytecode retrieval for contract execution traced: exists=${exists}, instance=${jsonStringify(contractInstance)}`,
);
}
diff --git a/yarn-project/txe/src/util/encoding.ts b/yarn-project/txe/src/util/encoding.ts
index 0b65122a61f..1853378af76 100644
--- a/yarn-project/txe/src/util/encoding.ts
+++ b/yarn-project/txe/src/util/encoding.ts
@@ -1,6 +1,7 @@
import { AztecAddress } from '@aztec/circuits.js';
import { type ContractArtifact, ContractArtifactSchema } from '@aztec/foundation/abi';
import { Fr } from '@aztec/foundation/fields';
+import { hexToBuffer } from '@aztec/foundation/string';
import { z } from 'zod';
@@ -23,7 +24,7 @@ export function addressFromSingle(obj: ForeignCallSingle) {
}
export function fromArray(obj: ForeignCallArray) {
- return obj.map(str => Fr.fromBuffer(Buffer.from(str, 'hex')));
+ return obj.map(str => Fr.fromBuffer(hexToBuffer(str)));
}
export function toSingle(obj: Fr | AztecAddress) {
diff --git a/yarn-project/types/src/abi/contract_artifact.ts b/yarn-project/types/src/abi/contract_artifact.ts
index 0141145e7b3..7e2f5b54bdd 100644
--- a/yarn-project/types/src/abi/contract_artifact.ts
+++ b/yarn-project/types/src/abi/contract_artifact.ts
@@ -13,6 +13,7 @@ import {
type StructValue,
type TypedStructFieldValue,
} from '@aztec/foundation/abi';
+import { jsonParseWithSchema, jsonStringify } from '@aztec/foundation/json-rpc';
import {
AZTEC_INITIALIZER_ATTRIBUTE,
@@ -29,21 +30,7 @@ import {
* @returns A buffer.
*/
export function contractArtifactToBuffer(artifact: ContractArtifact): Buffer {
- 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',
- );
+ return Buffer.from(jsonStringify(artifact), 'utf-8');
}
/**
@@ -52,7 +39,7 @@ export function contractArtifactToBuffer(artifact: ContractArtifact): Buffer {
* @returns Deserialized artifact.
*/
export function contractArtifactFromBuffer(buffer: Buffer): ContractArtifact {
- return ContractArtifactSchema.parse(JSON.parse(buffer.toString('utf-8')));
+ return jsonParseWithSchema(buffer.toString('utf-8'), ContractArtifactSchema);
}
/**
diff --git a/yarn-project/world-state/package.json b/yarn-project/world-state/package.json
index 29b1124e272..6ffcf4bd889 100644
--- a/yarn-project/world-state/package.json
+++ b/yarn-project/world-state/package.json
@@ -71,7 +71,8 @@
"@aztec/types": "workspace:^",
"bindings": "^1.5.0",
"msgpackr": "^1.10.2",
- "tslib": "^2.4.0"
+ "tslib": "^2.4.0",
+ "zod": "^3.23.8"
},
"devDependencies": {
"@aztec/archiver": "workspace:^",
diff --git a/yarn-project/world-state/src/native/world_state_version.ts b/yarn-project/world-state/src/native/world_state_version.ts
index 20707d354ab..2be422b9e16 100644
--- a/yarn-project/world-state/src/native/world_state_version.ts
+++ b/yarn-project/world-state/src/native/world_state_version.ts
@@ -1,38 +1,29 @@
import { EthAddress } from '@aztec/circuits.js';
+import { jsonParseWithSchema, jsonStringify } from '@aztec/foundation/json-rpc';
import { readFile, writeFile } from 'fs/promises';
+import { z } from 'zod';
export class WorldStateVersion {
- constructor(readonly version: number, readonly rollupAddress: EthAddress) {}
+ constructor(public readonly version: number, public readonly rollupAddress: EthAddress) {}
static async readVersion(filename: string) {
const versionData = await readFile(filename, 'utf-8').catch(() => undefined);
- if (versionData === undefined) {
- return undefined;
- }
- const versionJSON = JSON.parse(versionData);
- if (versionJSON.version === undefined || versionJSON.rollupAddress === undefined) {
- return undefined;
- }
- return WorldStateVersion.fromJSON(versionJSON);
+ return versionData === undefined ? undefined : jsonParseWithSchema(versionData, WorldStateVersion.schema);
}
public async writeVersionFile(filename: string) {
- const data = JSON.stringify(this.toJSON());
+ const data = jsonStringify(this);
await writeFile(filename, data, 'utf-8');
}
- toJSON() {
- return {
- version: this.version,
- rollupAddress: this.rollupAddress.toChecksumString(),
- };
- }
-
- static fromJSON(obj: any): WorldStateVersion {
- const version = obj.version;
- const rollupAddress = EthAddress.fromString(obj.rollupAddress);
- return new WorldStateVersion(version, rollupAddress);
+ static get schema() {
+ return z
+ .object({
+ version: z.number(),
+ rollupAddress: EthAddress.schema,
+ })
+ .transform(({ version, rollupAddress }) => new WorldStateVersion(version, rollupAddress));
}
static empty() {
diff --git a/yarn-project/yarn.lock b/yarn-project/yarn.lock
index 57c3aa91fda..2d0af3c2c7c 100644
--- a/yarn-project/yarn.lock
+++ b/yarn-project/yarn.lock
@@ -1328,6 +1328,7 @@ __metadata:
ts-node: ^10.9.1
tslib: ^2.4.0
typescript: ^5.0.4
+ zod: ^3.23.8
languageName: unknown
linkType: soft