zk-credits 0.2.2 → 0.2.3

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.
@@ -2,6 +2,7 @@ import { randomUUID } from 'node:crypto';
2
2
  import { chmod, lstat, mkdir, open, readFile, readdir, realpath, rename, rm, } from 'node:fs/promises';
3
3
  import { dirname, join, resolve } from 'node:path';
4
4
  import { resolvePinnedArtifactBundle } from './artifact-bundle.js';
5
+ import { acquirePinnedArtifactBundle } from './artifact-release.js';
5
6
  const WITNESS_FILENAMES = new Set([
6
7
  'base-tree.json',
7
8
  'base-sepolia-tree.json',
@@ -137,26 +138,55 @@ async function resolveArtifactDirectory(options, saved) {
137
138
  throw new Error('The configured proving bundle at ' + explicit + ' failed its pinned checks.' + reason);
138
139
  }
139
140
  if (valid.size === 0) {
140
- throw new Error('Could not find a valid pinned proving bundle. Extract the bundle from your pilot contact into ~/.zk-credits/artifacts/base-sepolia or ~/Downloads, or set ZK_CREDITS_ARTIFACT_DIR.');
141
+ if (options.manifest.release && !explicit) {
142
+ const targetDirectory = resolve(options.stateDirectory, 'artifacts', 'base-sepolia');
143
+ const acquire = options.acquireArtifactBundle ?? (async (target, manifest) => {
144
+ await acquirePinnedArtifactBundle({ manifest, targetDirectory: target });
145
+ });
146
+ await acquire(targetDirectory, options.manifest);
147
+ const bundle = await resolvePinnedArtifactBundle({ artifactDirectory: targetDirectory, manifest: options.manifest });
148
+ return resolve(bundle.directory);
149
+ }
150
+ throw new Error('Could not find a valid pinned proving bundle. Set ZK_CREDITS_ARTIFACT_DIR to a verified local bundle.');
141
151
  }
142
152
  const selected = await chooseOne('proving bundle', [...valid.values()], options.chooseCandidate);
143
153
  return resolve(selected);
144
154
  }
145
- function eventSourceFromEnvironment(environment) {
155
+ function eventSourceFromEnvironment(environment, manifest) {
146
156
  const rpcUrl = environment.BASE_RPC_URL?.trim();
147
- const contractAddress = environment.BASE_PRIVATE_CREDIT_BOND_ADDRESS?.trim();
157
+ const configuredContract = environment.BASE_PRIVATE_CREDIT_BOND_ADDRESS?.trim();
158
+ const configuredBlock = optionalEnvironmentInteger(environment, 'BASE_DEPLOYMENT_BLOCK');
159
+ const deployment = manifest.deployment;
160
+ if (deployment) {
161
+ if (configuredContract && configuredContract.toLowerCase() !== deployment.bondAddress.toLowerCase()) {
162
+ throw new Error('BASE_PRIVATE_CREDIT_BOND_ADDRESS does not match the pinned Base Sepolia V2 bond');
163
+ }
164
+ if (configuredBlock && configuredBlock !== deployment.deploymentBlock) {
165
+ throw new Error('BASE_DEPLOYMENT_BLOCK does not match the pinned Base Sepolia V2 deployment block');
166
+ }
167
+ }
168
+ const contractAddress = deployment?.bondAddress ?? configuredContract;
148
169
  if (!rpcUrl || !contractAddress)
149
170
  return undefined;
150
- const deploymentBlock = optionalEnvironmentInteger(environment, 'BASE_DEPLOYMENT_BLOCK');
151
171
  const confirmations = optionalEnvironmentInteger(environment, 'BASE_CONFIRMATIONS');
152
172
  return {
153
173
  kind: 'base-events',
154
174
  rpcUrl,
155
175
  contractAddress,
156
- ...(deploymentBlock === undefined ? {} : { deploymentBlock }),
176
+ ...(deployment ? { deploymentBlock: deployment.deploymentBlock } : configuredBlock === undefined ? {} : { deploymentBlock: configuredBlock }),
157
177
  ...(confirmations === undefined ? {} : { confirmations }),
158
178
  };
159
179
  }
180
+ function assertPinnedEventSource(source, manifest) {
181
+ const deployment = manifest.deployment;
182
+ if (!deployment)
183
+ return;
184
+ if (source.kind !== 'base-events'
185
+ || source.contractAddress.toLowerCase() !== deployment.bondAddress.toLowerCase()
186
+ || source.deploymentBlock !== deployment.deploymentBlock) {
187
+ throw new Error('Saved Base event witness source does not match the pinned Base Sepolia V2 deployment');
188
+ }
189
+ }
160
190
  function witnessCandidates(homeDirectory, stateDirectory) {
161
191
  const roots = [
162
192
  join(stateDirectory, 'witnesses'),
@@ -170,6 +200,9 @@ async function resolveWitnessSource(options, saved) {
170
200
  const environment = options.environment;
171
201
  const explicitPath = environment.ZK_CREDITS_WITNESS_PATH?.trim();
172
202
  if (explicitPath) {
203
+ if (options.manifest.deployment) {
204
+ throw new Error('Base Sepolia V2 setup requires a witness synchronized from the pinned public Base events');
205
+ }
173
206
  const source = {
174
207
  kind: 'file',
175
208
  path: resolve(options.workingDirectory ?? process.cwd(), explicitPath),
@@ -183,7 +216,7 @@ async function resolveWitnessSource(options, saved) {
183
216
  throw new Error('The configured Base witness at ' + explicitPath + ' failed validation.' + reason);
184
217
  }
185
218
  }
186
- const environmentSource = eventSourceFromEnvironment(environment);
219
+ const environmentSource = eventSourceFromEnvironment(environment, options.manifest);
187
220
  if (environmentSource) {
188
221
  try {
189
222
  await options.validateWitness(environmentSource);
@@ -196,6 +229,7 @@ async function resolveWitnessSource(options, saved) {
196
229
  }
197
230
  if (saved?.witness.kind === 'base-events') {
198
231
  try {
232
+ assertPinnedEventSource(saved.witness, options.manifest);
199
233
  await options.validateWitness(saved.witness);
200
234
  return saved.witness;
201
235
  }
@@ -204,6 +238,9 @@ async function resolveWitnessSource(options, saved) {
204
238
  throw new Error('Saved Base event witness source failed validation.' + reason);
205
239
  }
206
240
  }
241
+ if (options.manifest.deployment) {
242
+ throw new Error('Base Sepolia V2 setup requires BASE_RPC_URL to sync the pinned V2 bond from its deployment block');
243
+ }
207
244
  if (saved?.witness.kind === 'file') {
208
245
  try {
209
246
  await options.validateWitness(saved.witness);