@aztec/stdlib 0.0.1-commit.fff30aa → 0.0.1-dev

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/dest/abi/abi.d.ts +8 -1
  2. package/dest/abi/abi.d.ts.map +1 -1
  3. package/dest/abi/abi.js +4 -0
  4. package/dest/abi/contract_artifact.d.ts +1 -1
  5. package/dest/abi/contract_artifact.d.ts.map +1 -1
  6. package/dest/abi/contract_artifact.js +14 -7
  7. package/dest/abi/encoder.d.ts +1 -1
  8. package/dest/abi/encoder.d.ts.map +1 -1
  9. package/dest/abi/encoder.js +32 -6
  10. package/dest/aztec-address/index.d.ts +3 -1
  11. package/dest/aztec-address/index.d.ts.map +1 -1
  12. package/dest/aztec-address/index.js +2 -0
  13. package/dest/block/l2_block_stream/l2_tips_store_base.d.ts +1 -1
  14. package/dest/block/l2_block_stream/l2_tips_store_base.d.ts.map +1 -1
  15. package/dest/block/l2_block_stream/l2_tips_store_base.js +16 -3
  16. package/dest/block/test/l2_tips_store_test_suite.js +1 -1
  17. package/dest/hash/hash.d.ts +10 -1
  18. package/dest/hash/hash.d.ts.map +1 -1
  19. package/dest/hash/hash.js +16 -2
  20. package/dest/interfaces/validator.d.ts +3 -6
  21. package/dest/interfaces/validator.d.ts.map +1 -1
  22. package/dest/logs/tag.d.ts +3 -2
  23. package/dest/logs/tag.d.ts.map +1 -1
  24. package/dest/logs/tag.js +4 -0
  25. package/dest/noir/index.d.ts +3 -1
  26. package/dest/noir/index.d.ts.map +1 -1
  27. package/dest/p2p/checkpoint_proposal.d.ts +2 -2
  28. package/dest/p2p/checkpoint_proposal.d.ts.map +1 -1
  29. package/dest/p2p/checkpoint_proposal.js +3 -15
  30. package/dest/tests/mocks.d.ts +1 -1
  31. package/dest/tests/mocks.d.ts.map +1 -1
  32. package/dest/tests/mocks.js +13 -16
  33. package/dest/tx/proven_tx.d.ts +3 -1
  34. package/dest/tx/proven_tx.d.ts.map +1 -1
  35. package/dest/tx/proven_tx.js +6 -0
  36. package/dest/tx/simulated_tx.d.ts +9 -1
  37. package/dest/tx/simulated_tx.d.ts.map +1 -1
  38. package/dest/update-checker/dev_version.d.ts +3 -0
  39. package/dest/update-checker/dev_version.d.ts.map +1 -0
  40. package/dest/update-checker/dev_version.js +1 -0
  41. package/dest/update-checker/index.d.ts +2 -1
  42. package/dest/update-checker/index.d.ts.map +1 -1
  43. package/dest/update-checker/index.js +1 -0
  44. package/dest/update-checker/package_version.d.ts +6 -3
  45. package/dest/update-checker/package_version.d.ts.map +1 -1
  46. package/dest/update-checker/package_version.js +8 -19
  47. package/package.json +11 -10
  48. package/src/abi/abi.ts +9 -0
  49. package/src/abi/contract_artifact.ts +11 -6
  50. package/src/abi/encoder.ts +42 -6
  51. package/src/aztec-address/index.ts +4 -0
  52. package/src/block/l2_block_stream/l2_tips_store_base.ts +17 -3
  53. package/src/block/test/l2_tips_store_test_suite.ts +1 -1
  54. package/src/hash/hash.ts +14 -2
  55. package/src/interfaces/validator.ts +1 -4
  56. package/src/logs/tag.ts +5 -1
  57. package/src/noir/index.ts +2 -0
  58. package/src/p2p/checkpoint_proposal.ts +10 -26
  59. package/src/tests/mocks.ts +14 -10
  60. package/src/tx/proven_tx.ts +6 -0
  61. package/src/update-checker/dev_version.ts +2 -0
  62. package/src/update-checker/index.ts +1 -0
  63. package/src/update-checker/package_version.ts +10 -23
@@ -12,6 +12,7 @@ import {
12
12
  import {
13
13
  type ABIParameter,
14
14
  type ABIParameterVisibility,
15
+ ARTIFACT_VERSION_BEFORE_INJECTION,
15
16
  type AbiType,
16
17
  type BasicValue,
17
18
  type ContractArtifact,
@@ -51,6 +52,10 @@ export function contractArtifactFromBuffer(buffer: Buffer): ContractArtifact {
51
52
  */
52
53
  export function loadContractArtifact(input: NoirCompiledContract): ContractArtifact {
53
54
  if (isContractArtifact(input)) {
55
+ // TODO(F-557): Remove this fallback once pre-version artifacts are no longer tested.
56
+ if (!(input as unknown as Record<string, unknown>).aztecVersion) {
57
+ return { ...input, aztecVersion: ARTIFACT_VERSION_BEFORE_INJECTION };
58
+ }
54
59
  return input;
55
60
  }
56
61
  return generateContractArtifact(input);
@@ -276,10 +281,9 @@ function getStorageLayout(input: NoirCompiledContract) {
276
281
  }
277
282
 
278
283
  /**
279
- * Given a Nargo output generates an Aztec-compatible contract artifact.
284
+ * Given a post-processed Nargo output defined as `contract` generates an Aztec-compatible contract artifact.
285
+ *
280
286
  * Does not include public bytecode, apart from the public_dispatch function.
281
- * @param compiled - Noir build output.
282
- * @returns Aztec contract build artifact.
283
287
  */
284
288
  function generateContractArtifact(contract: NoirCompiledContract): ContractArtifact {
285
289
  try {
@@ -288,6 +292,7 @@ function generateContractArtifact(contract: NoirCompiledContract): ContractArtif
288
292
  }
289
293
  return ContractArtifactSchema.parse({
290
294
  name: contract.name,
295
+ aztecVersion: contract.aztec_version,
291
296
  functions: contract.functions.filter(f => retainBytecode(f)).map(f => generateFunctionArtifact(f, contract)),
292
297
  nonDispatchPublicFunctions: contract.functions
293
298
  .filter(f => !retainBytecode(f))
@@ -302,15 +307,15 @@ function generateContractArtifact(contract: NoirCompiledContract): ContractArtif
302
307
  }
303
308
 
304
309
  /**
305
- * Given a Nargo output generates an Aztec-compatible contract artifact.
310
+ * Given a post-processed Nargo output defined as `contract` generates an Aztec-compatible contract artifact.
311
+ *
306
312
  * Retains all public bytecode.
307
- * @param compiled - Noir build output.
308
- * @returns Aztec contract build artifact.
309
313
  */
310
314
  function generateContractArtifactForPublic(contract: NoirCompiledContract): ContractArtifact {
311
315
  try {
312
316
  return ContractArtifactSchema.parse({
313
317
  name: contract.name,
318
+ aztecVersion: contract.aztec_version,
314
319
  functions: contract.functions.map(f => generateFunctionArtifact(f, contract)),
315
320
  nonDispatchPublicFunctions: contract.functions
316
321
  .filter(f => !retainBytecode(f))
@@ -106,13 +106,28 @@ class ArgumentEncoder {
106
106
  this.flattened.push(new Fr(arg ? 1n : 0n));
107
107
  break;
108
108
  case 'array':
109
+ if (!Array.isArray(arg)) {
110
+ throw new Error(`Expected array for '${name ?? 'unnamed'}' but received ${typeof arg}`);
111
+ }
112
+ if (arg.length !== abiType.length) {
113
+ throw new Error(
114
+ `Expected array of length ${abiType.length} for '${name ?? 'unnamed'}' but received length ${arg.length}`,
115
+ );
116
+ }
109
117
  for (let i = 0; i < abiType.length; i += 1) {
110
118
  this.encodeArgument(abiType.type, arg[i], `${name}[${i}]`);
111
119
  }
112
120
  break;
113
121
  case 'string':
122
+ if (typeof arg !== 'string') {
123
+ throw new Error(`Expected string for '${name ?? 'unnamed'}' but received ${typeof arg}`);
124
+ }
125
+ if (arg.length > abiType.length) {
126
+ throw new Error(
127
+ `Expected string of max length ${abiType.length} for '${name ?? 'unnamed'}' but received length ${arg.length}`,
128
+ );
129
+ }
114
130
  for (let i = 0; i < abiType.length; i += 1) {
115
- // If the string is shorter than the defined length, pad it with 0s.
116
131
  const toInsert = i < arg.length ? BigInt((arg as string).charCodeAt(i)) : 0n;
117
132
  this.flattened.push(new Fr(toInsert));
118
133
  }
@@ -157,12 +172,28 @@ class ArgumentEncoder {
157
172
  }
158
173
  case 'integer': {
159
174
  const value = BigInt(arg);
160
- if (abiType.sign === 'signed' && value < 0n) {
161
- // Convert negative values to two's complement representation
162
- const twosComplement = value + (1n << BigInt(abiType.width));
163
- this.flattened.push(new Fr(twosComplement));
164
- } else {
175
+ if (abiType.sign === 'unsigned') {
176
+ const maxValue = (1n << BigInt(abiType.width)) - 1n;
177
+ if (value < 0n || value > maxValue) {
178
+ throw new Error(
179
+ `Value ${value} does not fit in u${abiType.width} for '${name ?? 'unnamed'}' (valid range: 0 to ${maxValue})`,
180
+ );
181
+ }
165
182
  this.flattened.push(new Fr(value));
183
+ } else {
184
+ const minValue = -(1n << BigInt(abiType.width - 1));
185
+ const maxValue = (1n << BigInt(abiType.width - 1)) - 1n;
186
+ if (value < minValue || value > maxValue) {
187
+ throw new Error(
188
+ `Value ${value} does not fit in i${abiType.width} for '${name ?? 'unnamed'}' (valid range: ${minValue} to ${maxValue})`,
189
+ );
190
+ }
191
+ if (value < 0n) {
192
+ const twosComplement = value + (1n << BigInt(abiType.width));
193
+ this.flattened.push(new Fr(twosComplement));
194
+ } else {
195
+ this.flattened.push(new Fr(value));
196
+ }
166
197
  }
167
198
  break;
168
199
  }
@@ -176,6 +207,11 @@ class ArgumentEncoder {
176
207
  * @returns The encoded arguments.
177
208
  */
178
209
  public encode() {
210
+ if (this.args.length !== this.abi.parameters.length) {
211
+ throw new Error(
212
+ `Function '${this.abi.name}' expects ${this.abi.parameters.length} argument(s) but received ${this.args.length}`,
213
+ );
214
+ }
179
215
  for (let i = 0; i < this.abi.parameters.length; i += 1) {
180
216
  const parameterAbi = this.abi.parameters[i];
181
217
  this.encodeArgument(parameterAbi.type, this.args[i], parameterAbi.name);
@@ -1,4 +1,5 @@
1
1
  /* eslint-disable @typescript-eslint/no-unsafe-declaration-merging */
2
+ import { NULL_MSG_SENDER_CONTRACT_ADDRESS } from '@aztec/constants';
2
3
  import { Fr, fromBuffer } from '@aztec/foundation/curves/bn254';
3
4
  import { Point } from '@aztec/foundation/curves/grumpkin';
4
5
  import { type ZodFor, bufferSchemaFor, hexSchemaFor } from '@aztec/foundation/schemas';
@@ -44,6 +45,9 @@ export class AztecAddress {
44
45
 
45
46
  static ZERO = new AztecAddress(Buffer.alloc(32, 0));
46
47
 
48
+ /** Null msg sender address. Not part of the protocol contracts tree. */
49
+ static NULL_MSG_SENDER = AztecAddress.fromBigInt(NULL_MSG_SENDER_CONTRACT_ADDRESS);
50
+
47
51
  static zero(): AztecAddress {
48
52
  return AztecAddress.ZERO;
49
53
  }
@@ -198,11 +198,25 @@ export abstract class L2TipsStoreBase implements L2BlockStreamEventHandler, L2Bl
198
198
  await this.saveTag('finalized', event.block);
199
199
  const finalizedCheckpointNumber = await this.getCheckpointNumberForBlock(event.block.number);
200
200
 
201
- await this.deleteBlockHashesBefore(event.block.number);
202
- await this.deleteBlockToCheckpointBefore(event.block.number);
201
+ // Cap the deletion bound at the lowest live tip. This should always be the finalized tip, but
202
+ // we have hit bugs where this is not the case. Deleting the block hash, block-to-checkpoint mapping,
203
+ // or enclosing checkpoint object for a live tip would dangle subsequent `getBlockId`/`getCheckpointId`
204
+ // lookups and lock the block stream into an error loop.
205
+ const tips = await Promise.all([this.getTip('proposed'), this.getTip('checkpointed'), this.getTip('proven')]);
206
+ const liveTipBlocks = tips.filter((t): t is BlockNumber => t !== undefined && t > 0);
207
+ const safeBlockBound = BlockNumber(Math.min(event.block.number, ...liveTipBlocks));
208
+ await this.deleteBlockHashesBefore(safeBlockBound);
209
+ await this.deleteBlockToCheckpointBefore(safeBlockBound);
203
210
 
204
211
  if (finalizedCheckpointNumber !== undefined) {
205
- await this.deleteCheckpointsBefore(finalizedCheckpointNumber);
212
+ const tipCheckpoints = await Promise.all(liveTipBlocks.map(b => this.getCheckpointNumberForBlock(b)));
213
+ const safeCheckpointBound = CheckpointNumber(
214
+ Math.min(
215
+ finalizedCheckpointNumber,
216
+ ...tipCheckpoints.filter((c): c is CheckpointNumber => c !== undefined && c > 0),
217
+ ),
218
+ );
219
+ await this.deleteCheckpointsBefore(safeCheckpointBound);
206
220
  }
207
221
  });
208
222
  }
@@ -11,7 +11,7 @@ import {
11
11
  } from '@aztec/stdlib/block';
12
12
  import { Checkpoint, L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
13
13
 
14
- import { jestExpect as expect } from '@jest/expect';
14
+ import { expect } from 'vitest';
15
15
 
16
16
  import type { L2TipsStore } from '../l2_block_stream/index.js';
17
17
 
package/src/hash/hash.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { DomainSeparator, NULL_MSG_SENDER_CONTRACT_ADDRESS } from '@aztec/constants';
1
+ import { DomainSeparator } from '@aztec/constants';
2
2
  import { poseidon2Hash, poseidon2HashWithSeparator } from '@aztec/foundation/crypto/poseidon';
3
3
  import { sha256ToField } from '@aztec/foundation/crypto/sha256';
4
4
  import { Fr } from '@aztec/foundation/curves/bn254';
@@ -95,7 +95,7 @@ export async function computeSiloedPublicInitializationNullifier(contract: Aztec
95
95
  * @dev Must match the implementation in noir-protocol-circuits/crates/types/src/hash.nr > compute_protocol_nullifier
96
96
  */
97
97
  export function computeProtocolNullifier(txRequestHash: Fr): Promise<Fr> {
98
- return siloNullifier(AztecAddress.fromBigInt(NULL_MSG_SENDER_CONTRACT_ADDRESS), txRequestHash);
98
+ return siloNullifier(AztecAddress.NULL_MSG_SENDER, txRequestHash);
99
99
  }
100
100
 
101
101
  /** Domain-separates a raw log tag with the given domain separator. */
@@ -103,6 +103,18 @@ export function computeLogTag(rawTag: number | bigint | boolean | Fr | Buffer, d
103
103
  return poseidon2HashWithSeparator([new Fr(rawTag)], domSep);
104
104
  }
105
105
 
106
+ /**
107
+ * Computes the commitment of a private event from its preimage.
108
+ * @param randomness - Random value emitted alongside the event to prevent preimage brute-forcing.
109
+ * @param eventSelector - Event selector as an Fr.
110
+ * @param content - Serialized event content.
111
+ *
112
+ * @dev Must match the implementation in aztec-nr/aztec/src/event/event_interface.nr > compute_private_serialized_event_commitment
113
+ */
114
+ export function computePrivateEventCommitment(randomness: Fr, eventSelector: Fr, content: Fr[]): Promise<Fr> {
115
+ return poseidon2HashWithSeparator([randomness, eventSelector, ...content], DomainSeparator.EVENT_COMMITMENT);
116
+ }
117
+
106
118
  export function computeSiloedPrivateLogFirstField(contract: AztecAddress, field: Fr): Promise<Fr> {
107
119
  return poseidon2HashWithSeparator([contract, field], DomainSeparator.PRIVATE_LOG_FIRST_FIELD);
108
120
  }
@@ -9,7 +9,6 @@ import type {
9
9
  BlockProposal,
10
10
  BlockProposalOptions,
11
11
  CheckpointAttestation,
12
- CheckpointLastBlockData,
13
12
  CheckpointProposal,
14
13
  CheckpointProposalOptions,
15
14
  } from '@aztec/stdlib/p2p';
@@ -116,8 +115,6 @@ export const ValidatorClientFullConfigSchema = zodFor<Omit<ValidatorClientFullCo
116
115
  }),
117
116
  );
118
117
 
119
- export type CreateCheckpointProposalLastBlockData = Omit<CheckpointLastBlockData, 'txHashes'> & { txs: Tx[] };
120
-
121
118
  export interface Validator {
122
119
  start(): Promise<void>;
123
120
  updateConfig(config: Partial<ValidatorClientFullConfig>): void;
@@ -138,7 +135,7 @@ export interface Validator {
138
135
  checkpointHeader: CheckpointHeader,
139
136
  archive: Fr,
140
137
  feeAssetPriceModifier: bigint,
141
- lastBlockInfo: CreateCheckpointProposalLastBlockData | undefined,
138
+ lastBlockProposal: BlockProposal | undefined,
142
139
  proposerAddress: EthAddress | undefined,
143
140
  options: CheckpointProposalOptions,
144
141
  ): Promise<CheckpointProposal>;
package/src/logs/tag.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { poseidon2Hash } from '@aztec/foundation/crypto/poseidon';
2
- import type { Fr } from '@aztec/foundation/curves/bn254';
2
+ import { Fr } from '@aztec/foundation/curves/bn254';
3
3
  import type { ZodFor } from '@aztec/foundation/schemas';
4
4
 
5
5
  import { schemas } from '../schemas/schemas.js';
@@ -36,6 +36,10 @@ export class Tag {
36
36
  return this.value.equals(other.value);
37
37
  }
38
38
 
39
+ static random(): Tag {
40
+ return new Tag(Fr.random());
41
+ }
42
+
39
43
  static get schema(): ZodFor<Tag> {
40
44
  return schemas.Fr.transform((fr: Fr) => new Tag(fr));
41
45
  }
package/src/noir/index.ts CHANGED
@@ -64,6 +64,8 @@ interface NoirFunctionEntry {
64
64
  export interface NoirCompiledContract {
65
65
  /** The name of the contract. */
66
66
  name: string;
67
+ /** The version of the Aztec stack that compiled this contract. */
68
+ aztec_version: string;
67
69
  /** Is the contract's public bytecode transpiled? */
68
70
  transpiled?: boolean;
69
71
  /** The functions of the contract. */
@@ -161,7 +161,7 @@ export class CheckpointProposal extends Gossipable {
161
161
  checkpointHeader: CheckpointHeader,
162
162
  archiveRoot: Fr,
163
163
  feeAssetPriceModifier: bigint,
164
- lastBlockInfo: CheckpointLastBlockData | undefined,
164
+ lastBlockProposal: BlockProposal | undefined,
165
165
  payloadSigner: (payload: Buffer32, context: SigningContext) => Promise<Signature>,
166
166
  ): Promise<CheckpointProposal> {
167
167
  // Sign the checkpoint payload with CHECKPOINT_PROPOSAL duty type
@@ -175,35 +175,19 @@ export class CheckpointProposal extends Gossipable {
175
175
 
176
176
  const checkpointContext: SigningContext = {
177
177
  slot: checkpointHeader.slotNumber,
178
- blockNumber: lastBlockInfo?.blockHeader?.globalVariables.blockNumber ?? BlockNumber(0),
178
+ blockNumber: lastBlockProposal?.blockNumber ?? BlockNumber(0),
179
179
  dutyType: DutyType.CHECKPOINT_PROPOSAL,
180
180
  };
181
181
 
182
- if (lastBlockInfo) {
183
- // Sign block proposal before signing checkpoint proposal to ensure HA protection
184
- const lastBlockProposal = await BlockProposal.createProposalFromSigner(
185
- lastBlockInfo.blockHeader,
186
- lastBlockInfo.indexWithinCheckpoint,
187
- checkpointHeader.inHash,
188
- archiveRoot,
189
- lastBlockInfo.txHashes,
190
- lastBlockInfo.txs,
191
- payloadSigner,
192
- );
193
-
194
- const checkpointSignature = await payloadSigner(checkpointHash, checkpointContext);
195
-
196
- return new CheckpointProposal(checkpointHeader, archiveRoot, feeAssetPriceModifier, checkpointSignature, {
197
- blockHeader: lastBlockInfo.blockHeader,
198
- indexWithinCheckpoint: lastBlockInfo.indexWithinCheckpoint,
199
- txHashes: lastBlockInfo.txHashes,
200
- signature: lastBlockProposal.signature,
201
- signedTxs: lastBlockProposal.signedTxs,
202
- });
203
- }
204
-
205
182
  const checkpointSignature = await payloadSigner(checkpointHash, checkpointContext);
206
- return new CheckpointProposal(checkpointHeader, archiveRoot, feeAssetPriceModifier, checkpointSignature);
183
+
184
+ return new CheckpointProposal(
185
+ checkpointHeader,
186
+ archiveRoot,
187
+ feeAssetPriceModifier,
188
+ checkpointSignature,
189
+ lastBlockProposal,
190
+ );
207
191
  }
208
192
 
209
193
  /**
@@ -72,6 +72,7 @@ import { NestedProcessReturnValues, PublicSimulationOutput } from '../tx/public_
72
72
  import { TxSimulationResult } from '../tx/simulated_tx.js';
73
73
  import { TxEffect } from '../tx/tx_effect.js';
74
74
  import { TxHash } from '../tx/tx_hash.js';
75
+ import { DEV_VERSION } from '../update-checker/dev_version.js';
75
76
  import {
76
77
  makeAvmCircuitInputs,
77
78
  makeAztecAddress,
@@ -479,6 +480,7 @@ export async function mockCheckpointAndMessages(
479
480
 
480
481
  export const randomContractArtifact = (): ContractArtifact => ({
481
482
  name: randomBytes(4).toString('hex'),
483
+ aztecVersion: DEV_VERSION,
482
484
  functions: [],
483
485
  nonDispatchPublicFunctions: [],
484
486
  outputs: {
@@ -596,28 +598,30 @@ export const makeBlockProposal = (options?: MakeBlockProposalOptions): Promise<B
596
598
  );
597
599
  };
598
600
 
599
- export const makeCheckpointProposal = (options?: MakeCheckpointProposalOptions): Promise<CheckpointProposal> => {
600
- const blockHeader = options?.lastBlock?.blockHeader ?? makeBlockHeader(1);
601
+ export const makeCheckpointProposal = async (options?: MakeCheckpointProposalOptions): Promise<CheckpointProposal> => {
601
602
  const checkpointHeader = options?.checkpointHeader ?? makeCheckpointHeader(1);
602
603
  const archiveRoot = options?.archiveRoot ?? Fr.random();
603
604
  const feeAssetPriceModifier = options?.feeAssetPriceModifier ?? 0n;
604
605
  const signer = options?.signer ?? Secp256k1Signer.random();
605
606
 
606
- // Build lastBlock info if provided
607
- const lastBlockInfo = options?.lastBlock
608
- ? {
609
- blockHeader,
610
- indexWithinCheckpoint: options.lastBlock.indexWithinCheckpoint ?? IndexWithinCheckpoint(4), // Last block in a 5-block checkpoint
611
- txHashes: options.lastBlock.txHashes ?? [0, 1, 2, 3, 4, 5].map(() => TxHash.random()),
607
+ // Build a signed block proposal if lastBlock options are provided
608
+ const lastBlockProposal = options?.lastBlock
609
+ ? await makeBlockProposal({
610
+ blockHeader: options.lastBlock.blockHeader,
611
+ indexWithinCheckpoint: options.lastBlock.indexWithinCheckpoint ?? IndexWithinCheckpoint(4),
612
+ inHash: checkpointHeader.inHash,
613
+ archiveRoot,
614
+ txHashes: options.lastBlock.txHashes,
612
615
  txs: options.lastBlock.txs,
613
- }
616
+ signer,
617
+ })
614
618
  : undefined;
615
619
 
616
620
  return CheckpointProposal.createProposalFromSigner(
617
621
  checkpointHeader,
618
622
  archiveRoot,
619
623
  feeAssetPriceModifier,
620
- lastBlockInfo,
624
+ lastBlockProposal,
621
625
  payload => Promise.resolve(signer.signMessage(payload)),
622
626
  );
623
627
  };
@@ -13,6 +13,7 @@ import {
13
13
  } from './private_execution_result.js';
14
14
  import { type ProvingStats, ProvingTimingsSchema } from './profiling.js';
15
15
  import { Tx } from './tx.js';
16
+ import type { TxHash } from './tx_hash.js';
16
17
 
17
18
  export class TxProvingResult {
18
19
  constructor(
@@ -22,6 +23,11 @@ export class TxProvingResult {
22
23
  public stats?: ProvingStats,
23
24
  ) {}
24
25
 
26
+ getTxHash(): Promise<TxHash> {
27
+ // Equivalent to `(await this.toTx()).txHash` but skips walking the execution result tree to collect logs.
28
+ return Tx.computeTxHash({ data: this.publicInputs });
29
+ }
30
+
25
31
  async toTx(): Promise<Tx> {
26
32
  const contractClassLogs = collectSortedContractClassLogs(this.privateExecutionResult);
27
33
 
@@ -0,0 +1,2 @@
1
+ /** Placeholder version returned when running from a local monorepo checkout rather than an npm-installed package. */
2
+ export const DEV_VERSION = 'dev';
@@ -1,2 +1,3 @@
1
+ export * from './dev_version.js';
1
2
  export * from './package_version.js';
2
3
  export * from './version_checker.js';
@@ -3,28 +3,15 @@ import { fileURLToPath } from '@aztec/foundation/url';
3
3
  import { readFileSync } from 'fs';
4
4
  import { dirname, resolve } from 'path';
5
5
 
6
- /** Returns the package version from the release-please manifest or the package.json, or undefined if not found. */
7
- export function getPackageVersion(): string | undefined {
8
- const dir = dirname(fileURLToPath(import.meta.url));
9
-
10
- // Try the release-please manifest first (works in dev/repo checkout).
11
- try {
12
- const releasePleaseManifestPath = resolve(dir, '../../../../.release-please-manifest.json');
13
- return JSON.parse(readFileSync(releasePleaseManifestPath).toString())['.'];
14
- } catch {
15
- // Not in a repo checkout, fall through.
16
- }
6
+ import { DEV_VERSION } from './dev_version.js';
17
7
 
18
- // Fall back to the stdlib package.json version (works in npm-installed packages).
19
- try {
20
- const packageJsonPath = resolve(dir, '../../package.json');
21
- const version = JSON.parse(readFileSync(packageJsonPath).toString()).version;
22
- if (version && version !== '0.1.0') {
23
- return version;
24
- }
25
- } catch {
26
- // No package.json found either.
27
- }
28
-
29
- return undefined;
8
+ /**
9
+ * Returns the package version from the stdlib `package.json`, or `DEV_VERSION` when the version is the `0.1.0`
10
+ * placeholder (which indicates a local monorepo checkout rather than an npm-installed package).
11
+ */
12
+ export function getPackageVersion(): string {
13
+ const dir = dirname(fileURLToPath(import.meta.url));
14
+ const packageJsonPath = resolve(dir, '../../package.json');
15
+ const version = JSON.parse(readFileSync(packageJsonPath).toString()).version;
16
+ return version === '0.1.0' ? DEV_VERSION : version;
30
17
  }