@hardkas/sdk 0.9.0-alpha → 0.9.1-alpha

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 (4) hide show
  1. package/README.md +51 -51
  2. package/dist/index.d.ts +492 -7
  3. package/dist/index.js +2101 -106
  4. package/package.json +13 -13
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ import { HardkasError as HardkasError3 } from "@hardkas/core";
11
11
 
12
12
  // src/accounts.ts
13
13
  import { resolveHardkasAccount } from "@hardkas/accounts";
14
- import { formatSompi } from "@hardkas/core";
14
+ import { formatSompiToKas } from "@hardkas/core";
15
15
  var HardkasAccounts = class {
16
16
  constructor(sdk) {
17
17
  this.sdk = sdk;
@@ -37,7 +37,7 @@ var HardkasAccounts = class {
37
37
  const sompi = BigInt(balanceSompi);
38
38
  return {
39
39
  sompi,
40
- formatted: formatSompi(sompi)
40
+ formatted: formatSompiToKas(sompi)
41
41
  };
42
42
  }
43
43
  /**
@@ -47,10 +47,12 @@ var HardkasAccounts = class {
47
47
  return this.getBalance(accountNameOrAddress);
48
48
  }
49
49
  /**
50
- * Lists all configured account names.
50
+ * Lists all available HardKAS accounts.
51
51
  */
52
52
  async list() {
53
- return Object.keys(this.sdk.config.config.accounts || {});
53
+ const { listHardkasAccounts, describeAccount } = await import("@hardkas/accounts");
54
+ const accounts = listHardkasAccounts({ ...this.sdk.config.config, cwd: this.sdk.workspace.root });
55
+ return accounts.map((a) => describeAccount(a));
54
56
  }
55
57
  /**
56
58
  * Funds an account from another account (defaults to 'default' account).
@@ -59,7 +61,8 @@ var HardkasAccounts = class {
59
61
  let from = options?.from;
60
62
  const amount = options?.amount || "1000000000";
61
63
  if (!from) {
62
- const accounts = await this.list();
64
+ const accountsList = await this.list();
65
+ const accounts = accountsList.map((a) => a.name);
63
66
  if (accounts.includes("faucet")) {
64
67
  from = "faucet";
65
68
  } else if (accounts.includes("simulated_faucet")) {
@@ -67,7 +70,9 @@ var HardkasAccounts = class {
67
70
  } else if (this.sdk.network === "simulated" && accounts.includes("alice")) {
68
71
  from = "alice";
69
72
  } else {
70
- throw new Error("No funding account available.\nFor simulated mode, run Hardkas.create({ network: 'simulated', autoBootstrap: true })\nor call accounts.fund(target, { from: 'alice' }).");
73
+ throw new Error(
74
+ "No funding account available.\nFor simulated mode, run Hardkas.create({ network: 'simulated', autoBootstrap: true })\nor call accounts.fund(target, { from: 'alice' })."
75
+ );
71
76
  }
72
77
  }
73
78
  if (from === accountNameOrAddress) {
@@ -105,16 +110,22 @@ import {
105
110
  getBroadcastableSignedTransaction
106
111
  } from "@hardkas/artifacts";
107
112
  import { coreEvents } from "@hardkas/core";
108
- import { signTxPlanArtifact, validateAddressNetwork } from "@hardkas/accounts";
113
+ import {
114
+ signTxPlanArtifact,
115
+ validateAddressNetwork
116
+ } from "@hardkas/accounts";
109
117
  import { parseKasToSompi } from "@hardkas/core";
110
118
  import { TxPlanService } from "@hardkas/tx-builder";
119
+ import { HardkasSchemas } from "@hardkas/artifacts";
111
120
  function normalizeSimulatedPlanInput(target, fallbackId) {
112
121
  if (target.schema === ARTIFACT_SCHEMAS.TX_PLAN && Array.isArray(target.inputs)) {
113
122
  return target;
114
123
  }
115
124
  if (target.from && target.to && target.amountSompi) {
116
125
  if (target.mode !== "simulated") {
117
- throw new Error("Cannot simulate real signed artifact without parent plan. Missing plan inputs data.");
126
+ throw new Error(
127
+ "Cannot simulate real signed artifact without parent plan. Missing plan inputs data."
128
+ );
118
129
  }
119
130
  return {
120
131
  schema: ARTIFACT_SCHEMAS.TX_PLAN,
@@ -130,14 +141,18 @@ function normalizeSimulatedPlanInput(target, fallbackId) {
130
141
  outputs: [{ address: target.to.address, amountSompi: target.amountSompi || "0" }],
131
142
  plan: {
132
143
  inputs: [],
133
- outputs: [{ address: target.to.address, amountSompi: BigInt(target.amountSompi || 0) }],
144
+ outputs: [
145
+ { address: target.to.address, amountSompi: BigInt(target.amountSompi || 0) }
146
+ ],
134
147
  feeSompi: 0n,
135
148
  mass: 0n,
136
149
  changeSompi: 0n
137
150
  }
138
151
  };
139
152
  }
140
- throw new Error("Cannot simulate signed artifact without parent plan or embedded plan data.");
153
+ throw new Error(
154
+ "Cannot simulate signed artifact without parent plan or embedded plan data."
155
+ );
141
156
  }
142
157
  var HardkasTx = class {
143
158
  constructor(sdk) {
@@ -156,7 +171,9 @@ var HardkasTx = class {
156
171
  throw new Error(`To account ${toAccount.name} has no address.`);
157
172
  const amountSompi = typeof options.amount === "string" ? parseKasToSompi(options.amount) : typeof options.amount === "number" ? parseKasToSompi(options.amount.toString()) : options.amount;
158
173
  if (amountSompi === 0n) {
159
- throw new Error("Kaspa value-transfer outputs require amount > 0.\nFor metadata/notary/DID marker transactions use --amount 1.\nFuture: hardkas tx anchor.");
174
+ throw new Error(
175
+ "Kaspa value-transfer outputs require amount > 0.\nFor metadata/notary/DID marker transactions use --amount 1.\nFuture: hardkas tx anchor."
176
+ );
160
177
  }
161
178
  const activeNetwork = this.sdk.config.config.defaultNetwork || "simnet";
162
179
  const allowMainnet = this.sdk.config.config.networks?.mainnet?.allowMainnet === true;
@@ -169,7 +186,9 @@ var HardkasTx = class {
169
186
  getUtxos: async (address) => {
170
187
  if (activeNetwork === "simulated" || this.sdk.config.config.networks?.[activeNetwork]?.kind === "simulated") {
171
188
  const { loadOrCreateLocalnetState, getSpendableUtxos } = await import("@hardkas/localnet");
172
- const localState = await loadOrCreateLocalnetState({ cwd: this.sdk.workspace.root });
189
+ const localState = await loadOrCreateLocalnetState({
190
+ cwd: this.sdk.workspace.root
191
+ });
173
192
  const unspent = getSpendableUtxos(localState, address);
174
193
  return unspent.map((u) => {
175
194
  const parts = u.id.split(":");
@@ -278,21 +297,25 @@ var HardkasTx = class {
278
297
  basePlan.assumptionRef = options.assumption;
279
298
  }
280
299
  }
281
- const { CURRENT_HASH_VERSION: CURRENT_HASH_VERSION2, calculateContentHash: calculateContentHash2 } = await import("@hardkas/artifacts");
282
- const newHash = calculateContentHash2(basePlan, CURRENT_HASH_VERSION2);
300
+ const { CURRENT_HASH_VERSION: CURRENT_HASH_VERSION3, calculateContentHash: calculateContentHash7 } = await import("@hardkas/artifacts");
301
+ const newHash = calculateContentHash7(basePlan, CURRENT_HASH_VERSION3);
283
302
  basePlan.contentHash = newHash;
284
303
  if (basePlan.lineage) {
285
304
  basePlan.lineage.lineageId = newHash;
286
305
  basePlan.lineage.parentArtifactId = "";
287
306
  basePlan.lineage.rootArtifactId = newHash;
288
- const finalHash = calculateContentHash2(basePlan, CURRENT_HASH_VERSION2);
307
+ const finalHash = calculateContentHash7(basePlan, CURRENT_HASH_VERSION3);
289
308
  basePlan.contentHash = finalHash;
290
309
  basePlan.lineage.artifactId = finalHash;
291
310
  basePlan.planId = `plan-${finalHash.slice(0, 16)}`;
292
311
  }
293
312
  this.sdk.artifacts.cacheArtifact(basePlan);
294
313
  if (basePlan.policyRefs && basePlan.policyRefs.length > 0) {
295
- await this.sdk.artifacts.verify(basePlan, { throwOnInvalid: true, strict: true, enforceMetadata: false });
314
+ await this.sdk.artifacts.verify(basePlan, {
315
+ throwOnInvalid: true,
316
+ strict: true,
317
+ enforceMetadata: false
318
+ });
296
319
  }
297
320
  return basePlan;
298
321
  }
@@ -308,7 +331,9 @@ var HardkasTx = class {
308
331
  resolvedAccount = options.account;
309
332
  }
310
333
  if (!resolvedAccount.address) {
311
- throw new Error(`Account '${resolvedAccount.name || options.account}' has no address.`);
334
+ throw new Error(
335
+ `Account '${resolvedAccount.name || options.account}' has no address.`
336
+ );
312
337
  }
313
338
  const activeNetwork = options.network || this.sdk.config.config.defaultNetwork || "simnet";
314
339
  const isSimulated = activeNetwork === "simulated" || this.sdk.config.config.networks?.[activeNetwork]?.kind === "simulated";
@@ -354,14 +379,14 @@ var HardkasTx = class {
354
379
  }
355
380
  }
356
381
  });
357
- const { CURRENT_HASH_VERSION: CURRENT_HASH_VERSION2, calculateContentHash: calculateContentHash2 } = await import("@hardkas/artifacts");
358
- const newHash = calculateContentHash2(basePlan, CURRENT_HASH_VERSION2);
382
+ const { CURRENT_HASH_VERSION: CURRENT_HASH_VERSION3, calculateContentHash: calculateContentHash7 } = await import("@hardkas/artifacts");
383
+ const newHash = calculateContentHash7(basePlan, CURRENT_HASH_VERSION3);
359
384
  basePlan.contentHash = newHash;
360
385
  if (basePlan.lineage) {
361
386
  basePlan.lineage.lineageId = newHash;
362
387
  basePlan.lineage.parentArtifactId = "";
363
388
  basePlan.lineage.rootArtifactId = newHash;
364
- const finalHash = calculateContentHash2(basePlan, CURRENT_HASH_VERSION2);
389
+ const finalHash = calculateContentHash7(basePlan, CURRENT_HASH_VERSION3);
365
390
  basePlan.contentHash = finalHash;
366
391
  basePlan.lineage.artifactId = finalHash;
367
392
  basePlan.planId = `plan-${finalHash.slice(0, 16)}`;
@@ -374,10 +399,16 @@ var HardkasTx = class {
374
399
  */
375
400
  async sign(plan, account, options) {
376
401
  if (typeof plan === "object" && plan !== null && plan.contentHash) {
377
- await this.sdk.artifacts.verify(plan, { throwOnInvalid: true, strict: true, enforceMetadata: false });
402
+ await this.sdk.artifacts.verify(plan, {
403
+ throwOnInvalid: true,
404
+ strict: true,
405
+ enforceMetadata: false
406
+ });
378
407
  }
379
- if (this.sdk.signer && plan.schema === "hardkas.txPlan") {
380
- const signedArtifact2 = await this.sdk.signer.signTransaction(plan);
408
+ if (this.sdk.signer && plan.schema === HardkasSchemas.TxPlan) {
409
+ const signedArtifact2 = await this.sdk.signer.signTransaction(
410
+ plan
411
+ );
381
412
  const { absolutePath: absolutePath2 } = await this.sdk.artifacts.write(signedArtifact2);
382
413
  const { coreEvents: coreEvents3 } = await import("@hardkas/core");
383
414
  const signedRecord2 = signedArtifact2;
@@ -413,7 +444,7 @@ var HardkasTx = class {
413
444
  resolvedAccount = await this.sdk.accounts.resolve(fromName);
414
445
  }
415
446
  let signedArtifact;
416
- if (plan.schema === "hardkas.signedTx") {
447
+ if (plan.schema === HardkasSchemas.SignedTx) {
417
448
  if (plan.status === "signed") {
418
449
  throw new Error(
419
450
  "Cannot append signature to an already completed signed transaction."
@@ -473,7 +504,7 @@ var HardkasTx = class {
473
504
  signatures: newSignatures
474
505
  },
475
506
  signatureMetadata: newMeta,
476
- lineage: createLineageTransition(partialTx, "hardkas.signedTx")
507
+ lineage: createLineageTransition(partialTx, HardkasSchemas.SignedTx)
477
508
  };
478
509
  if (thresholdReached) {
479
510
  draft.signedTransaction = {
@@ -485,13 +516,13 @@ var HardkasTx = class {
485
516
  delete draft.signedTransaction;
486
517
  delete draft.txId;
487
518
  }
488
- const { CURRENT_HASH_VERSION: CURRENT_HASH_VERSION2 } = await import("@hardkas/artifacts");
489
- const hash = calculateContentHash(draft, CURRENT_HASH_VERSION2);
519
+ const { CURRENT_HASH_VERSION: CURRENT_HASH_VERSION3 } = await import("@hardkas/artifacts");
520
+ const hash = calculateContentHash(draft, CURRENT_HASH_VERSION3);
490
521
  draft.signedId = `signed-${hash.slice(0, 16)}`;
491
522
  draft.contentHash = hash;
492
523
  if (draft.lineage) draft.lineage.artifactId = hash;
493
524
  signedArtifact = draft;
494
- } else if (plan.schema === "hardkas.txPlan") {
525
+ } else if (plan.schema === HardkasSchemas.TxPlan) {
495
526
  if (options?.append) {
496
527
  throw new Error(
497
528
  "Do not use --append for the first signature of a transaction plan."
@@ -529,13 +560,13 @@ var HardkasTx = class {
529
560
  ];
530
561
  const thresholdReached = signatures.length >= threshold;
531
562
  const finalStatus = thresholdReached ? "signed" : "partially_signed";
532
- const { HARDKAS_VERSION: HARDKAS_VERSION4, ARTIFACT_VERSION: ARTIFACT_VERSION2, CURRENT_HASH_VERSION: CURRENT_HASH_VERSION2 } = await import("@hardkas/artifacts");
563
+ const { HARDKAS_VERSION: HARDKAS_VERSION6, ARTIFACT_VERSION: ARTIFACT_VERSION2, CURRENT_HASH_VERSION: CURRENT_HASH_VERSION3 } = await import("@hardkas/artifacts");
533
564
  const draft = {
534
- schema: "hardkas.signedTx",
535
- schemaVersion: "hardkas.artifact.v1",
536
- hardkasVersion: HARDKAS_VERSION4,
565
+ schema: HardkasSchemas.SignedTx,
566
+ schemaVersion: HardkasSchemas.ArtifactV1,
567
+ hardkasVersion: HARDKAS_VERSION6,
537
568
  version: ARTIFACT_VERSION2,
538
- hashVersion: CURRENT_HASH_VERSION2,
569
+ hashVersion: CURRENT_HASH_VERSION3,
539
570
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
540
571
  status: finalStatus,
541
572
  sourcePlanId: plan.planId,
@@ -551,7 +582,7 @@ var HardkasTx = class {
551
582
  signatures
552
583
  },
553
584
  signatureMetadata,
554
- lineage: createLineageTransition(plan, "hardkas.signedTx"),
585
+ lineage: createLineageTransition(plan, HardkasSchemas.SignedTx),
555
586
  ...plan.workflowId ? { workflowId: plan.workflowId } : {}
556
587
  };
557
588
  if (thresholdReached) {
@@ -561,19 +592,21 @@ var HardkasTx = class {
561
592
  };
562
593
  draft.txId = `simulated-${plan.planId}-tx`;
563
594
  }
564
- let hash = calculateContentHash(draft, CURRENT_HASH_VERSION2);
595
+ let hash = calculateContentHash(draft, CURRENT_HASH_VERSION3);
565
596
  draft.signedId = `signed-${hash.slice(0, 16)}`;
566
597
  draft.contentHash = hash;
567
598
  if (draft.lineage) {
568
599
  draft.lineage.artifactId = hash;
569
- hash = calculateContentHash(draft, CURRENT_HASH_VERSION2);
600
+ hash = calculateContentHash(draft, CURRENT_HASH_VERSION3);
570
601
  draft.contentHash = hash;
571
602
  draft.lineage.artifactId = hash;
572
603
  }
573
604
  signedArtifact = draft;
574
605
  } else {
575
606
  if (resolvedAccount.address !== plan.from.address) {
576
- throw new Error(`Signer account '${resolvedAccount.address}' is not authorized to sign for '${plan.from.address}'.`);
607
+ throw new Error(
608
+ `Signer account '${resolvedAccount.address}' is not authorized to sign for '${plan.from.address}'.`
609
+ );
577
610
  }
578
611
  signedArtifact = await signTxPlanArtifact({
579
612
  planArtifact: plan,
@@ -613,7 +646,11 @@ var HardkasTx = class {
613
646
  async simulate(target, options = {}) {
614
647
  if (typeof target === "object" && target !== null && target.contentHash) {
615
648
  try {
616
- await this.sdk.artifacts.verify(target, { throwOnInvalid: true, strict: true, enforceMetadata: false });
649
+ await this.sdk.artifacts.verify(target, {
650
+ throwOnInvalid: true,
651
+ strict: true,
652
+ enforceMetadata: false
653
+ });
617
654
  } catch (e) {
618
655
  if (e.message.includes("PARENT_MISSING")) {
619
656
  throw new Error("parent_plan_unresolved: Missing context plan for simulation.");
@@ -626,7 +663,9 @@ var HardkasTx = class {
626
663
  const checkTxId = target.txId || (target.schema === ARTIFACT_SCHEMAS.SIGNED_TX ? `simulated-${target.sourcePlanId || "unknown"}-tx` : `simulated-${target.planId || target.id || "unknown"}-tx`);
627
664
  if (checkTxId) {
628
665
  try {
629
- const existingReceipt = await this.sdk.artifacts.read(checkTxId, { expectedSchema: ARTIFACT_SCHEMAS.TX_RECEIPT });
666
+ const existingReceipt = await this.sdk.artifacts.read(checkTxId, {
667
+ expectedSchema: ARTIFACT_SCHEMAS.TX_RECEIPT
668
+ });
630
669
  if (existingReceipt && existingReceipt.schema === ARTIFACT_SCHEMAS.TX_RECEIPT) {
631
670
  const receiptPath2 = getDefaultReceiptPath(checkTxId, this.sdk.config.cwd);
632
671
  return { receipt: existingReceipt, receiptPath: receiptPath2 };
@@ -643,7 +682,7 @@ var HardkasTx = class {
643
682
  saveSimulatedReceipt,
644
683
  saveSimulatedTrace
645
684
  } = await import("@hardkas/localnet");
646
- const path4 = await import("path");
685
+ const path9 = await import("path");
647
686
  const state = await loadOrCreateLocalnetState({ cwd: this.sdk.workspace.root });
648
687
  const startTime = Date.now();
649
688
  const events = [
@@ -656,9 +695,13 @@ var HardkasTx = class {
656
695
  let targetObj = target;
657
696
  if (typeof target === "string") {
658
697
  try {
659
- targetObj = await this.sdk.artifacts.read(target, { expectedSchema: ARTIFACT_SCHEMAS.TX_PLAN });
698
+ targetObj = await this.sdk.artifacts.read(target, {
699
+ expectedSchema: ARTIFACT_SCHEMAS.TX_PLAN
700
+ });
660
701
  } catch (e) {
661
- throw new Error(`Artifact '${target}' not found. If you already have an in-memory artifact, pass the object directly to tx.simulate(artifact).`);
702
+ throw new Error(
703
+ `Artifact '${target}' not found. If you already have an in-memory artifact, pass the object directly to tx.simulate(artifact).`
704
+ );
662
705
  }
663
706
  }
664
707
  if (targetObj.schema === ARTIFACT_SCHEMAS.SIGNED_TX) {
@@ -668,7 +711,9 @@ var HardkasTx = class {
668
711
  planArtifact = this.sdk.artifacts.getCached(sourcePlanId);
669
712
  if (!planArtifact) {
670
713
  try {
671
- planArtifact = await this.sdk.artifacts.read(sourcePlanId, { expectedSchema: ARTIFACT_SCHEMAS.TX_PLAN });
714
+ planArtifact = await this.sdk.artifacts.read(sourcePlanId, {
715
+ expectedSchema: ARTIFACT_SCHEMAS.TX_PLAN
716
+ });
672
717
  } catch (e) {
673
718
  throw new Error("parent_plan_unresolved");
674
719
  }
@@ -714,7 +759,7 @@ var HardkasTx = class {
714
759
  const isSimulated = activeNetwork === "simulated" || this.sdk.config.config.networks?.[activeNetwork]?.kind === "simulated";
715
760
  const receiptBase = {
716
761
  schema: ARTIFACT_SCHEMAS.TX_RECEIPT,
717
- schemaVersion: "hardkas.receipt.v1",
762
+ schemaVersion: HardkasSchemas.TxReceiptV1,
718
763
  hardkasVersion: HARDKAS_VERSION,
719
764
  version: ARTIFACT_VERSION,
720
765
  hashVersion: CURRENT_HASH_VERSION,
@@ -816,7 +861,11 @@ var HardkasTx = class {
816
861
  async send(signedArtifact, urlOrOptions) {
817
862
  if (typeof signedArtifact === "object" && signedArtifact !== null && signedArtifact.contentHash) {
818
863
  try {
819
- await this.sdk.artifacts.verify(signedArtifact, { throwOnInvalid: true, strict: true, enforceMetadata: false });
864
+ await this.sdk.artifacts.verify(signedArtifact, {
865
+ throwOnInvalid: true,
866
+ strict: true,
867
+ enforceMetadata: false
868
+ });
820
869
  } catch (e) {
821
870
  if (e.message.includes("PARENT_MISSING")) {
822
871
  throw new Error("parent_plan_unresolved: Missing context plan for simulation.");
@@ -844,7 +893,9 @@ var HardkasTx = class {
844
893
  try {
845
894
  const { loadSimulatedReceipt, getReceiptPath } = await import("@hardkas/localnet");
846
895
  const txIdToLoad = signedArtifact.txId || `simulated-${signedArtifact.sourcePlanId}-tx`;
847
- const existingReceipt = await loadSimulatedReceipt(txIdToLoad, { cwd: this.sdk.workspace.root });
896
+ const existingReceipt = await loadSimulatedReceipt(txIdToLoad, {
897
+ cwd: this.sdk.workspace.root
898
+ });
848
899
  if (existingReceipt) {
849
900
  if (existingReceipt.schema === ARTIFACT_SCHEMAS.TX_RECEIPT && (existingReceipt.status === "confirmed" || existingReceipt.status === "accepted")) {
850
901
  return {
@@ -855,7 +906,10 @@ var HardkasTx = class {
855
906
  artifactId: existingReceipt.txId,
856
907
  // simulated receipts use txId as artifactId
857
908
  receipt: existingReceipt,
858
- receiptPath: getReceiptPath(existingReceipt.txId, this.sdk.workspace.root)
909
+ receiptPath: getReceiptPath(
910
+ existingReceipt.txId,
911
+ this.sdk.workspace.root
912
+ )
859
913
  };
860
914
  }
861
915
  }
@@ -910,7 +964,7 @@ var HardkasTx = class {
910
964
  ...signedArtifact.networkProfileRef ? { networkProfileRef: signedArtifact.networkProfileRef } : {},
911
965
  ...signedArtifact.assumptionRef ? { assumptionRef: signedArtifact.assumptionRef } : {},
912
966
  tracePath: void 0,
913
- lineage: createLineageTransition(signedArtifact, "hardkas.txReceipt")
967
+ lineage: createLineageTransition(signedArtifact, HardkasSchemas.TxReceipt)
914
968
  };
915
969
  realReceiptBase.contentHash = calculateContentHash(
916
970
  realReceiptBase,
@@ -918,7 +972,10 @@ var HardkasTx = class {
918
972
  );
919
973
  if (realReceiptBase.lineage) {
920
974
  realReceiptBase.lineage.artifactId = realReceiptBase.contentHash;
921
- realReceiptBase.contentHash = calculateContentHash(realReceiptBase, CURRENT_HASH_VERSION);
975
+ realReceiptBase.contentHash = calculateContentHash(
976
+ realReceiptBase,
977
+ CURRENT_HASH_VERSION
978
+ );
922
979
  realReceiptBase.lineage.artifactId = realReceiptBase.contentHash;
923
980
  }
924
981
  const receipt = realReceiptBase;
@@ -989,11 +1046,13 @@ var HardkasQuery = class {
989
1046
  * Synchronizes the query store with the filesystem artifacts.
990
1047
  */
991
1048
  async sync(options) {
992
- const fs4 = await import("fs");
993
- const path4 = await import("path");
994
- const hardkasDir = path4.join(this.sdk.workspace.root, ".hardkas");
995
- if (!fs4.existsSync(hardkasDir)) {
996
- throw new Error("Workspace not initialized. Run hardkas init or Hardkas.create({ autoBootstrap:true }).");
1049
+ const fs9 = await import("fs");
1050
+ const path9 = await import("path");
1051
+ const hardkasDir = path9.join(this.sdk.workspace.root, ".hardkas");
1052
+ if (!fs9.existsSync(hardkasDir)) {
1053
+ throw new Error(
1054
+ "Workspace not initialized. Run hardkas init or Hardkas.create({ autoBootstrap:true })."
1055
+ );
997
1056
  }
998
1057
  let HardkasStore, HardkasIndexer;
999
1058
  try {
@@ -1001,10 +1060,12 @@ var HardkasQuery = class {
1001
1060
  HardkasStore = qs.HardkasStore;
1002
1061
  HardkasIndexer = qs.HardkasIndexer;
1003
1062
  } catch (e) {
1004
- throw new Error("Query store backend unavailable. Install @hardkas/query-store or run query.store.rebuild.");
1063
+ throw new Error(
1064
+ "Query store backend unavailable. Install @hardkas/query-store or run query.store.rebuild."
1065
+ );
1005
1066
  }
1006
1067
  const { withLock } = await import("@hardkas/core");
1007
- const dbPath = path4.join(hardkasDir, "store.db");
1068
+ const dbPath = path9.join(hardkasDir, "store.db");
1008
1069
  const store = new HardkasStore({ dbPath });
1009
1070
  let stats;
1010
1071
  try {
@@ -1027,7 +1088,9 @@ var HardkasQuery = class {
1027
1088
  );
1028
1089
  } catch (e) {
1029
1090
  if (e.message?.includes("SQLITE") || e.message?.includes("Cannot read properties")) {
1030
- throw new Error("Query store database is not configured correctly or corrupted. Try running query.sync({ force: true }).");
1091
+ throw new Error(
1092
+ "Query store database is not configured correctly or corrupted. Try running query.sync({ force: true })."
1093
+ );
1031
1094
  }
1032
1095
  throw e;
1033
1096
  }
@@ -1056,6 +1119,8 @@ var HardkasQuery = class {
1056
1119
  };
1057
1120
 
1058
1121
  // src/localnet.ts
1122
+ import { execFileSync } from "child_process";
1123
+ import { HardkasSchemas as HardkasSchemas2 } from "@hardkas/artifacts";
1059
1124
  var HardkasLocalnet = class {
1060
1125
  constructor(sdk) {
1061
1126
  this.sdk = sdk;
@@ -1073,17 +1138,141 @@ var HardkasLocalnet = class {
1073
1138
  }
1074
1139
  }
1075
1140
  /**
1076
- * Future: control localnet process/container from here.
1141
+ * Status check with the same claim boundaries as `hardkas localnet status --json`.
1142
+ */
1143
+ async status(options = {}) {
1144
+ const profile = options.profile || "toccata-v2";
1145
+ const node = await this.detectToccataNode();
1146
+ return {
1147
+ schema: HardkasSchemas2.LocalnetStatusV1,
1148
+ profile,
1149
+ node,
1150
+ miner: this.inspectDockerContainer("hardkas-toccata-stratum-v2"),
1151
+ simulationLevels: {
1152
+ artifactCoherence: "READY",
1153
+ runtimeOutcome: "PARTIAL",
1154
+ vmConsensusEquivalence: "NOT_CLAIMED"
1155
+ }
1156
+ };
1157
+ }
1158
+ /**
1159
+ * Initializes the in-memory simulated workspace.
1160
+ *
1161
+ * Docker Toccata process control remains a CLI/localnet responsibility in
1162
+ * 0.9.1-alpha; the SDK reports that boundary instead of silently shelling out.
1163
+ */
1164
+ async start(options = {}) {
1165
+ const profile = options.profile || "simulated";
1166
+ if (profile === "simulated") {
1167
+ const { loadOrCreateLocalnetState } = await import("@hardkas/localnet");
1168
+ await loadOrCreateLocalnetState({ cwd: this.sdk.cwd });
1169
+ return {
1170
+ schema: HardkasSchemas2.LocalnetControlV1,
1171
+ profile,
1172
+ status: "SIMULATED_LOCALNET_READY",
1173
+ message: "Simulated localnet state is ready."
1174
+ };
1175
+ }
1176
+ return {
1177
+ schema: HardkasSchemas2.LocalnetControlV1,
1178
+ profile,
1179
+ status: "SDK_LOCALNET_CONTROL_UNSUPPORTED",
1180
+ message: "SDK Docker localnet start is not supported in 0.9.1-alpha. Use `hardkas localnet start --profile toccata-v2`."
1181
+ };
1182
+ }
1183
+ /**
1184
+ * Funds a simulated account through the SDK transaction flow.
1185
+ *
1186
+ * Toccata Docker mining/funding remains CLI-only in 0.9.1-alpha because it
1187
+ * depends on a local stratum/miner companion and host Docker state.
1077
1188
  */
1078
- async start() {
1079
- console.log("Localnet control via SDK is not yet implemented.");
1080
- console.log("Please use 'hardkas localnet' CLI command.");
1189
+ async fund(identifier, options = {}) {
1190
+ const profile = options.profile || (this.sdk.network === "simulated" ? "simulated" : "toccata-v2");
1191
+ if (profile === "simulated") {
1192
+ const fundOptions = {};
1193
+ if (options.from !== void 0) fundOptions.from = options.from;
1194
+ if (options.amount !== void 0) fundOptions.amount = options.amount;
1195
+ const receipt = await this.sdk.accounts.fund(identifier, fundOptions);
1196
+ return {
1197
+ schema: HardkasSchemas2.LocalnetFundingV1,
1198
+ profile,
1199
+ identifier,
1200
+ status: "SIMULATED_ACCOUNT_FUNDED",
1201
+ receipt,
1202
+ message: "Simulated account funded through SDK transaction simulation."
1203
+ };
1204
+ }
1205
+ return {
1206
+ schema: HardkasSchemas2.LocalnetFundingV1,
1207
+ profile,
1208
+ identifier,
1209
+ status: "SDK_TOCCATA_FUNDING_UNSUPPORTED",
1210
+ message: "SDK Toccata funding is not supported in 0.9.1-alpha. Use `hardkas localnet fund <account> --profile toccata-v2`."
1211
+ };
1081
1212
  }
1082
1213
  /**
1083
1214
  * Resets the localnet state (simulated or node).
1084
1215
  */
1085
1216
  async reset() {
1086
- console.log("Localnet reset via SDK is not yet implemented.");
1217
+ const { resetLocalnetState } = await import("@hardkas/localnet");
1218
+ await resetLocalnetState({ cwd: this.sdk.cwd });
1219
+ }
1220
+ async detectToccataNode() {
1221
+ const rpcUrl = "ws://127.0.0.1:18210";
1222
+ const { JsonWrpcKaspaClient: JsonWrpcKaspaClient2 } = await import("@hardkas/kaspa-rpc");
1223
+ const client = new JsonWrpcKaspaClient2({ rpcUrl, timeoutMs: 3e3 });
1224
+ try {
1225
+ const server = await client.getServerInfo();
1226
+ const info = await client.getInfo();
1227
+ const serverNetworkId = String(server.networkId || "");
1228
+ const result = {
1229
+ ready: true,
1230
+ rpcUrl,
1231
+ networkId: serverNetworkId === "unknown" ? "simnet" : server.networkId || info.networkId || "simnet",
1232
+ serverVersion: server.serverVersion || info.serverVersion,
1233
+ isSynced: server.isSynced ?? info.isSynced,
1234
+ virtualDaaScore: info.virtualDaaScore?.toString()
1235
+ };
1236
+ await client.close();
1237
+ return result;
1238
+ } catch (error) {
1239
+ await client.close().catch(() => {
1240
+ });
1241
+ return {
1242
+ ready: false,
1243
+ rpcUrl,
1244
+ lastError: error?.message || String(error)
1245
+ };
1246
+ }
1247
+ }
1248
+ inspectDockerContainer(name) {
1249
+ const image = "hardkas/stratum-bridge:v2.0.0-local-simnet-unsynced";
1250
+ try {
1251
+ const stdout = execFileSync(
1252
+ "docker",
1253
+ ["inspect", "--format", "{{.State.Status}}|{{.Config.Image}}|{{.Name}}", name],
1254
+ {
1255
+ encoding: "utf8",
1256
+ stdio: "pipe"
1257
+ }
1258
+ );
1259
+ const [status, detectedImage, rawName] = stdout.trim().split("|");
1260
+ return {
1261
+ exists: true,
1262
+ running: status === "running",
1263
+ status: status || "unknown",
1264
+ image: detectedImage || image,
1265
+ name: rawName?.replace(/^\//, "") || name
1266
+ };
1267
+ } catch {
1268
+ return {
1269
+ exists: false,
1270
+ running: false,
1271
+ status: "not-found",
1272
+ image,
1273
+ name
1274
+ };
1275
+ }
1087
1276
  }
1088
1277
  };
1089
1278
 
@@ -1097,6 +1286,7 @@ import {
1097
1286
  writeArtifact as writeArtifact2
1098
1287
  } from "@hardkas/artifacts";
1099
1288
  import { deterministicCompare as deterministicCompare2 } from "@hardkas/core";
1289
+ import { HardkasSchemas as HardkasSchemas3 } from "@hardkas/artifacts";
1100
1290
  function resolveReplayTargets(cwd, options) {
1101
1291
  if (options.path) {
1102
1292
  const fullPath = path.resolve(cwd, options.path);
@@ -1150,13 +1340,13 @@ function resolveFromDirectory(dir, source) {
1150
1340
  const raw = fs.readFileSync(path.join(dir, f), "utf-8");
1151
1341
  const data = JSON.parse(raw);
1152
1342
  if (!data || !data.schema) continue;
1153
- if (data.schema === "hardkas.txPlan") {
1343
+ if (data.schema === HardkasSchemas3.TxPlan) {
1154
1344
  plans.push({
1155
1345
  file: f,
1156
1346
  planId: data.planId || "",
1157
1347
  createdAt: data.createdAt || ""
1158
1348
  });
1159
- } else if (data.schema === "hardkas.txReceipt") {
1349
+ } else if (data.schema === HardkasSchemas3.TxReceipt) {
1160
1350
  receipts.push({
1161
1351
  file: f,
1162
1352
  sourcePlanId: data.sourcePlanId || data.lineage?.parentArtifactId || data.lineage?.rootArtifactId || "",
@@ -1207,7 +1397,7 @@ function findReceiptByPlanId(dir, planId) {
1207
1397
  try {
1208
1398
  const raw = fs.readFileSync(path.join(dir, f), "utf-8");
1209
1399
  const data = JSON.parse(raw);
1210
- if (data && data.schema === "hardkas.txReceipt" && (data.sourcePlanId && data.sourcePlanId === planId || data.lineage?.parentArtifactId && data.lineage.parentArtifactId === planId || data.lineage?.rootArtifactId && data.lineage.rootArtifactId === planId || data.txId && data.txId.includes(planId))) {
1400
+ if (data && data.schema === HardkasSchemas3.TxReceipt && (data.sourcePlanId && data.sourcePlanId === planId || data.lineage?.parentArtifactId && data.lineage.parentArtifactId === planId || data.lineage?.rootArtifactId && data.lineage.rootArtifactId === planId || data.txId && data.txId.includes(planId))) {
1211
1401
  return path.join(dir, f);
1212
1402
  }
1213
1403
  } catch {
@@ -1227,7 +1417,10 @@ var HardkasReplay = class {
1227
1417
  async verify(targetOrOptions, options) {
1228
1418
  const throwOnInvalid = options?.throwOnInvalid !== false;
1229
1419
  if (typeof targetOrOptions === "object" && targetOrOptions !== null && targetOrOptions.contentHash) {
1230
- const verifyRes = await this.sdk.artifacts.verify(targetOrOptions, { throwOnInvalid, strict: true });
1420
+ const verifyRes = await this.sdk.artifacts.verify(targetOrOptions, {
1421
+ throwOnInvalid,
1422
+ strict: true
1423
+ });
1231
1424
  if (!verifyRes.valid && !throwOnInvalid) {
1232
1425
  return {
1233
1426
  passed: false,
@@ -1298,10 +1491,10 @@ var HardkasReplay = class {
1298
1491
  artifactCount++;
1299
1492
  if (isContaminated(json)) contaminationOk = false;
1300
1493
  const isCoreArtifact = [
1301
- "hardkas.txPlan",
1302
- "hardkas.signedTx",
1303
- "hardkas.txReceipt",
1304
- "hardkas.snapshot"
1494
+ HardkasSchemas3.TxPlan,
1495
+ HardkasSchemas3.SignedTx,
1496
+ HardkasSchemas3.TxReceipt,
1497
+ HardkasSchemas3.Snapshot
1305
1498
  ].includes(json.schema);
1306
1499
  if (isCoreArtifact) {
1307
1500
  const integrity = await verifyArtifactIntegrity(json);
@@ -1328,7 +1521,7 @@ var HardkasReplay = class {
1328
1521
  "utf-8"
1329
1522
  );
1330
1523
  const wfArtifact = JSON.parse(wfArtifactStr);
1331
- if (wfArtifact.schema !== "hardkas.workflow.v1") {
1524
+ if (wfArtifact.schema !== HardkasSchemas3.WorkflowV1) {
1332
1525
  throw new Error(`Artifact ${opts.workflowId} is not a workflow artifact`);
1333
1526
  }
1334
1527
  const childArtifacts = wfArtifact.producedArtifacts || [];
@@ -1504,8 +1697,8 @@ var HardkasArtifactsManager = class {
1504
1697
  async write(artifact, options = {}) {
1505
1698
  const record = artifact;
1506
1699
  if (!record.hashVersion) {
1507
- const { CURRENT_HASH_VERSION: CURRENT_HASH_VERSION2 } = await import("@hardkas/artifacts");
1508
- record.hashVersion = CURRENT_HASH_VERSION2;
1700
+ const { CURRENT_HASH_VERSION: CURRENT_HASH_VERSION3 } = await import("@hardkas/artifacts");
1701
+ record.hashVersion = CURRENT_HASH_VERSION3;
1509
1702
  }
1510
1703
  const hash = record.contentHash || "unknown";
1511
1704
  if (record.planId) this.cache.set(record.planId, artifact);
@@ -1526,8 +1719,8 @@ var HardkasArtifactsManager = class {
1526
1719
  const shortSchema = schema.replace("hardkas.", "");
1527
1720
  const fileName = options.fileName || `${shortSchema}-${hash}.json`;
1528
1721
  const absolutePath = path3.join(outputDir, fileName);
1529
- const { writeArtifact: writeArtifact4 } = await import("@hardkas/artifacts");
1530
- await writeArtifact4(absolutePath, artifact);
1722
+ const { writeArtifact: writeArtifact5 } = await import("@hardkas/artifacts");
1723
+ await writeArtifact5(absolutePath, artifact);
1531
1724
  const {
1532
1725
  coreEvents: coreEvents2,
1533
1726
  createEventEnvelope,
@@ -1580,7 +1773,10 @@ var HardkasArtifactsManager = class {
1580
1773
  const rootRel = path3.relative(this.workspace.root, resolvedPath);
1581
1774
  const artifactsRel = path3.relative(this.workspace.artifactsDir, resolvedPath);
1582
1775
  if ((rootRel.startsWith("..") || path3.isAbsolute(rootRel)) && (artifactsRel.startsWith("..") || path3.isAbsolute(artifactsRel))) {
1583
- throw new HardkasError("PATH_TRAVERSAL", "Artifact path escapes workspace boundary");
1776
+ throw new HardkasError(
1777
+ "PATH_TRAVERSAL",
1778
+ "Artifact path escapes workspace boundary"
1779
+ );
1584
1780
  }
1585
1781
  if (!fs3.existsSync(filePath)) {
1586
1782
  filePath = path3.join(this.workspace.artifactsDir, `${id}.json`);
@@ -1618,7 +1814,9 @@ var HardkasArtifactsManager = class {
1618
1814
  }
1619
1815
  const artifact = await readArtifact(filePath);
1620
1816
  if (options?.expectedSchema && artifact.schema !== options.expectedSchema) {
1621
- throw new Error(`Artifact ${id} has schema '${artifact.schema}' but expected '${options.expectedSchema}'`);
1817
+ throw new Error(
1818
+ `Artifact ${id} has schema '${artifact.schema}' but expected '${options.expectedSchema}'`
1819
+ );
1622
1820
  }
1623
1821
  return artifact;
1624
1822
  }
@@ -1641,7 +1839,9 @@ var HardkasArtifactsManager = class {
1641
1839
  for (const file of files) {
1642
1840
  if (file.endsWith(".json")) {
1643
1841
  try {
1644
- const artifact = await readArtifact(path3.join(this.workspace.artifactsDir, file));
1842
+ const artifact = await readArtifact(
1843
+ path3.join(this.workspace.artifactsDir, file)
1844
+ );
1645
1845
  artifacts.push(artifact);
1646
1846
  } catch (e) {
1647
1847
  }
@@ -1662,14 +1862,24 @@ var HardkasArtifactsManager = class {
1662
1862
  if (typeof target === "string") {
1663
1863
  id = target;
1664
1864
  if (!id) {
1665
- if (throwOnInvalid) throw new Error("No artifact target provided for verification.");
1666
- return { valid: false, reason: "unknown", message: "No artifact target provided for verification." };
1865
+ if (throwOnInvalid)
1866
+ throw new Error("No artifact target provided for verification.");
1867
+ return {
1868
+ valid: false,
1869
+ reason: "unknown",
1870
+ message: "No artifact target provided for verification."
1871
+ };
1667
1872
  }
1668
1873
  try {
1669
1874
  artifact = await this.read(id);
1670
1875
  } catch (e) {
1671
1876
  if (throwOnInvalid) throw e;
1672
- return { valid: false, reason: "missing_artifact", message: e.message, artifactId: id };
1877
+ return {
1878
+ valid: false,
1879
+ reason: "missing_artifact",
1880
+ message: e.message,
1881
+ artifactId: id
1882
+ };
1673
1883
  }
1674
1884
  } else {
1675
1885
  artifact = target;
@@ -1693,7 +1903,9 @@ var HardkasArtifactsManager = class {
1693
1903
  if (!result.ok) {
1694
1904
  const mappedReason = result.issues[0]?.code === "HASH_MISMATCH" ? "content_hash_mismatch" : result.issues[0]?.code === "MISSING_CONTENT_HASH" ? "missing_content_hash" : result.issues[0]?.code === "MISSING_SIGNATURE" ? "missing_signature" : result.issues[0]?.code === "REFERENCE_MISSING" ? "reference_missing" : result.issues[0]?.code === "REFERENCE_HASH_MISMATCH" ? "reference_hash_mismatch" : result.issues[0]?.code === "POLICY_VIOLATION" ? "policy_violation" : result.issues[0]?.code === "LEGACY_HASH_VERSION_UNSAFE" ? "legacy_hash_version_unsafe" : result.issues[0]?.code === "PARENT_MISSING" ? "parent_missing" : "schema_invalid";
1695
1905
  if (throwOnInvalid) {
1696
- throw new Error(`Artifact ${id} corrupted or invalid: ` + JSON.stringify(result.issues, null, 2));
1906
+ throw new Error(
1907
+ `Artifact ${id} corrupted or invalid: ` + JSON.stringify(result.issues, null, 2)
1908
+ );
1697
1909
  }
1698
1910
  return {
1699
1911
  valid: false,
@@ -1723,7 +1935,9 @@ var HardkasArtifactsManager = class {
1723
1935
  const { migrateArtifactPayload, generateMigrationReceipt } = await import("@hardkas/artifacts");
1724
1936
  const result = migrateArtifactPayload(artifact, void 0, { strictPolicy: false });
1725
1937
  if (!result.migrated) {
1726
- throw new Error(`Artifact ${artifact.artifactId || artifact.contentHash} is already at the target version or cannot be migrated.`);
1938
+ throw new Error(
1939
+ `Artifact ${artifact.artifactId || artifact.contentHash} is already at the target version or cannot be migrated.`
1940
+ );
1727
1941
  }
1728
1942
  const receipt = generateMigrationReceipt(artifact, result.artifact, migrationId);
1729
1943
  await this.write(result.artifact);
@@ -1735,6 +1949,7 @@ var HardkasArtifactsManager = class {
1735
1949
  // src/workflow.ts
1736
1950
  import { HARDKAS_VERSION as HARDKAS_VERSION2 } from "@hardkas/artifacts";
1737
1951
  import { HardkasError as HardkasError2, deterministicCompare as deterministicCompare3 } from "@hardkas/core";
1952
+ import { HardkasSchemas as HardkasSchemas4 } from "@hardkas/artifacts";
1738
1953
  var HardkasWorkflow = class {
1739
1954
  constructor(sdk) {
1740
1955
  this.sdk = sdk;
@@ -1744,9 +1959,9 @@ var HardkasWorkflow = class {
1744
1959
  * Executes a sequence of declarative steps and returns a definitive WorkflowArtifact.
1745
1960
  */
1746
1961
  async run(options) {
1747
- const { calculateContentHash: calculateContentHash2 } = await import("@hardkas/artifacts");
1962
+ const { calculateContentHash: calculateContentHash7 } = await import("@hardkas/artifacts");
1748
1963
  const intentPayload = {
1749
- type: "hardkas.workflow.intent",
1964
+ type: HardkasSchemas4.WorkflowIntent,
1750
1965
  schemaVersion: "v1",
1751
1966
  workflowSpec: options.steps,
1752
1967
  normalizedInputs: {},
@@ -1763,9 +1978,9 @@ var HardkasWorkflow = class {
1763
1978
  network: this.sdk.network
1764
1979
  },
1765
1980
  runtimeVersion: HARDKAS_VERSION2,
1766
- workspaceSchemaVersion: "hardkas.workflow.v1"
1981
+ workspaceSchemaVersion: HardkasSchemas4.WorkflowV1
1767
1982
  };
1768
- const intentHash = calculateContentHash2(intentPayload);
1983
+ const intentHash = calculateContentHash7(intentPayload);
1769
1984
  const workflowId = `wf_${intentHash.slice(0, 16)}`;
1770
1985
  const artifactSteps = [];
1771
1986
  const producedArtifacts = [];
@@ -1916,7 +2131,6 @@ var HardkasWorkflow = class {
1916
2131
  if (producedArtifactId) stepRecord.producedArtifactId = producedArtifactId;
1917
2132
  artifactSteps.push(stepRecord);
1918
2133
  } catch (e) {
1919
- console.error("DEBUG WORKFLOW ERROR:", e.stack);
1920
2134
  status = "failed";
1921
2135
  errorEnvelope = {
1922
2136
  code: e.code || "WORKFLOW_STEP_FAILED",
@@ -1936,7 +2150,7 @@ var HardkasWorkflow = class {
1936
2150
  }
1937
2151
  const executionMode = this.sdk.network === "simulated" ? "simulated" : "real";
1938
2152
  const artifact = {
1939
- schema: "hardkas.workflow.v1",
2153
+ schema: HardkasSchemas4.WorkflowV1,
1940
2154
  version: "1.0.0-alpha",
1941
2155
  hardkasVersion: HARDKAS_VERSION2,
1942
2156
  networkId: this.sdk.network,
@@ -1966,7 +2180,7 @@ var HardkasWorkflow = class {
1966
2180
  if (errorEnvelope) {
1967
2181
  artifact.errorEnvelope = errorEnvelope;
1968
2182
  }
1969
- artifact.contentHash = calculateContentHash2(artifact, 1);
2183
+ artifact.contentHash = calculateContentHash7(artifact, 1);
1970
2184
  if (!options.dryRun) {
1971
2185
  this.sdk.enforcePolicy("mutation", "Workflow Runtime saving artifact");
1972
2186
  await this.sdk.artifacts.write(artifact, {
@@ -1977,6 +2191,1750 @@ var HardkasWorkflow = class {
1977
2191
  }
1978
2192
  };
1979
2193
 
2194
+ // src/capabilities.ts
2195
+ import { CURRENT_HASH_VERSION as CURRENT_HASH_VERSION2, HARDKAS_VERSION as HARDKAS_VERSION3 } from "@hardkas/artifacts";
2196
+ var HardkasCapabilitiesApi = class {
2197
+ async get() {
2198
+ return createHardkasCapabilities();
2199
+ }
2200
+ };
2201
+ function createHardkasCapabilities() {
2202
+ return {
2203
+ version: HARDKAS_VERSION3,
2204
+ maturity: "hardened-alpha",
2205
+ proofVersion: "repro-v0",
2206
+ hashVersion: CURRENT_HASH_VERSION2,
2207
+ capabilities: {
2208
+ artifacts: true,
2209
+ lineageVerification: true,
2210
+ deterministicHashing: true,
2211
+ atomicPersistence: true,
2212
+ workspaceLocks: true,
2213
+ corruptionDetection: true,
2214
+ secretRedaction: true,
2215
+ mainnetGuards: true,
2216
+ localnetSimulation: true,
2217
+ ghostdagSimulation: true,
2218
+ dagConflictResolution: true,
2219
+ massProfiler: true,
2220
+ simulationScenarios: true,
2221
+ queryStore: true,
2222
+ replayVerification: true,
2223
+ schemaMigrations: true,
2224
+ dockerNode: true,
2225
+ scriptRunner: true,
2226
+ testingFramework: true,
2227
+ l2Profiles: true,
2228
+ l2BridgeAssumptions: true,
2229
+ consensusValidation: false,
2230
+ productionWallet: false,
2231
+ silverScript: false,
2232
+ covenants: false,
2233
+ trustlessExit: false,
2234
+ differentialDagValidation: false
2235
+ },
2236
+ trustBoundaries: {
2237
+ replay: "local-workflow-only",
2238
+ artifacts: "internal-integrity-only",
2239
+ simulator: "research-experimental",
2240
+ queryStore: "rebuildable-read-model",
2241
+ l2Bridge: "pre-zk-assumptions"
2242
+ }
2243
+ };
2244
+ }
2245
+
2246
+ // src/corpus.ts
2247
+ import fs4 from "fs";
2248
+ import path4 from "path";
2249
+ import { calculateContentHash as calculateContentHash2 } from "@hardkas/artifacts";
2250
+ import { HardkasSchemas as HardkasSchemas5 } from "@hardkas/artifacts";
2251
+ var EXPECTED_LIMITATION = "PARTIAL_VM_SIMULATION";
2252
+ var HardkasCorpus = class {
2253
+ constructor(sdk) {
2254
+ this.sdk = sdk;
2255
+ }
2256
+ sdk;
2257
+ async verify(targetPath) {
2258
+ return verifyToccataCorpus(targetPath, this.sdk.cwd);
2259
+ }
2260
+ };
2261
+ function verifyToccataCorpus(targetPath, workspaceRoot = process.cwd()) {
2262
+ const corpusPath = path4.resolve(workspaceRoot, targetPath);
2263
+ const issues = [];
2264
+ const opTrueDir = path4.join(corpusPath, "op-true");
2265
+ const failuresDir = path4.join(corpusPath, "failures");
2266
+ const opManifestPath = path4.join(opTrueDir, "manifest.json");
2267
+ const failureManifestPath = path4.join(failuresDir, "manifest.json");
2268
+ const opManifest = readRequiredJson(opManifestPath, issues);
2269
+ const failureManifest = readRequiredJson(failureManifestPath, issues);
2270
+ if (opManifest) {
2271
+ expectEqual(
2272
+ opManifest.schema,
2273
+ HardkasSchemas5.ToccataGoldenManifestV1,
2274
+ issues,
2275
+ "OP_TRUE_SCHEMA_INVALID",
2276
+ opManifestPath
2277
+ );
2278
+ validateCommonClaims(opManifest, issues, opManifestPath);
2279
+ }
2280
+ if (failureManifest) {
2281
+ expectEqual(
2282
+ failureManifest.schema,
2283
+ HardkasSchemas5.ToccataGoldenFailureManifestV1,
2284
+ issues,
2285
+ "FAILURE_SCHEMA_INVALID",
2286
+ failureManifestPath
2287
+ );
2288
+ validateCommonClaims(failureManifest, issues, failureManifestPath);
2289
+ }
2290
+ let artifactsChecked = 0;
2291
+ if (Array.isArray(opManifest?.files)) {
2292
+ for (const file of opManifest.files) {
2293
+ const filePath = path4.join(opTrueDir, file);
2294
+ if (!fs4.existsSync(filePath)) {
2295
+ issues.push({
2296
+ code: "CORPUS_FILE_MISSING",
2297
+ message: `Missing referenced OP_TRUE file ${file}.`,
2298
+ file: filePath
2299
+ });
2300
+ continue;
2301
+ }
2302
+ if (file === "manifest.json" || file === "compare-report.json") continue;
2303
+ const artifact = readRequiredJson(filePath, issues);
2304
+ if (!artifact) continue;
2305
+ artifactsChecked += 1;
2306
+ verifyContentHash(artifact, issues, filePath);
2307
+ }
2308
+ }
2309
+ const comparePath = path4.join(opTrueDir, "compare-report.json");
2310
+ const compareReport = readRequiredJson(comparePath, issues);
2311
+ if (compareReport) {
2312
+ expectEqual(
2313
+ compareReport.schema,
2314
+ HardkasSchemas5.ToccataGoldenCompareV1,
2315
+ issues,
2316
+ "COMPARE_SCHEMA_INVALID",
2317
+ comparePath
2318
+ );
2319
+ expectEqual(
2320
+ compareReport.compareMode,
2321
+ "artifact-coherence",
2322
+ issues,
2323
+ "COMPARE_MODE_INVALID",
2324
+ comparePath
2325
+ );
2326
+ expectEqual(
2327
+ compareReport.status,
2328
+ "SILVERSCRIPT_SIMULATION_MATCH",
2329
+ issues,
2330
+ "COMPARE_STATUS_INVALID",
2331
+ comparePath
2332
+ );
2333
+ if (!Array.isArray(compareReport.drift) || compareReport.drift.length !== 0) {
2334
+ issues.push({
2335
+ code: "COMPARE_DRIFT_NOT_EMPTY",
2336
+ message: "artifact-coherence compare report must not contain drift.",
2337
+ file: comparePath
2338
+ });
2339
+ }
2340
+ expectKnownLimitation(compareReport, issues, comparePath);
2341
+ const strictNotes = compareReport.semanticNotes || [];
2342
+ if (!Array.isArray(strictNotes) || strictNotes.length === 0) {
2343
+ issues.push({
2344
+ code: "STRICT_DRIFT_NOT_DECLARED",
2345
+ message: "Strict/runtime lineage differences must be declared as semantic notes.",
2346
+ file: comparePath
2347
+ });
2348
+ }
2349
+ }
2350
+ let failureFixtures = 0;
2351
+ if (Array.isArray(failureManifest?.cases)) {
2352
+ for (const entry of failureManifest.cases) {
2353
+ failureFixtures += 1;
2354
+ const filePath = path4.join(failuresDir, entry.file);
2355
+ const fixture = readRequiredJson(filePath, issues);
2356
+ if (!fixture) continue;
2357
+ expectEqual(
2358
+ fixture.schema,
2359
+ HardkasSchemas5.ToccataGoldenFailureCaseV1,
2360
+ issues,
2361
+ "FAILURE_CASE_SCHEMA_INVALID",
2362
+ filePath
2363
+ );
2364
+ if (!entry.expectedSimulatorError) {
2365
+ issues.push({
2366
+ code: "EXPECTED_SIMULATOR_ERROR_MISSING",
2367
+ message: `Failure case ${entry.caseId} must declare expectedSimulatorError.`,
2368
+ file: failureManifestPath
2369
+ });
2370
+ }
2371
+ const expectedError = fixture.expectedSimulator?.error || fixture.expectedSimulator?.secondAttempt?.error;
2372
+ expectEqual(
2373
+ expectedError,
2374
+ entry.expectedSimulatorError,
2375
+ issues,
2376
+ "EXPECTED_SIMULATOR_ERROR_MISMATCH",
2377
+ filePath
2378
+ );
2379
+ validateFailureReferences(fixture, issues, filePath, corpusPath);
2380
+ if (entry.caseId === "mainnet-guard") {
2381
+ validateMainnetGuard(entry, fixture, issues, filePath);
2382
+ }
2383
+ }
2384
+ }
2385
+ const ok = issues.length === 0;
2386
+ return {
2387
+ ok,
2388
+ schema: HardkasSchemas5.ToccataCorpusV1,
2389
+ path: path4.relative(workspaceRoot, corpusPath).replace(/\\/g, "/"),
2390
+ summary: {
2391
+ happyPathFixtures: opManifest ? 1 : 0,
2392
+ failureFixtures,
2393
+ artifactsChecked,
2394
+ contentHashes: issues.some((issue) => issue.code.includes("HASH")) ? "FAIL" : "PASS",
2395
+ compareMode: compareReport?.compareMode ?? "unknown",
2396
+ simulationStatus: compareReport?.status ?? "unknown",
2397
+ knownLimitations: collectKnownLimitations(
2398
+ opManifest,
2399
+ failureManifest,
2400
+ compareReport
2401
+ )
2402
+ },
2403
+ claims: {
2404
+ artifactCoherence: ok ? "READY_MATCH" : "INVALID",
2405
+ runtimeOutcome: ok ? "PARTIAL" : "INVALID",
2406
+ vmConsensusEquivalence: ok ? "NOT_CLAIMED" : "INVALID",
2407
+ mainnet: ok ? "BLOCKED_BY_POLICY" : "INVALID"
2408
+ },
2409
+ issues
2410
+ };
2411
+ }
2412
+ function readRequiredJson(filePath, issues) {
2413
+ if (!fs4.existsSync(filePath)) {
2414
+ issues.push({
2415
+ code: "FILE_MISSING",
2416
+ message: `Missing required file ${filePath}.`,
2417
+ file: filePath
2418
+ });
2419
+ return void 0;
2420
+ }
2421
+ try {
2422
+ return JSON.parse(fs4.readFileSync(filePath, "utf8"));
2423
+ } catch (error) {
2424
+ issues.push({
2425
+ code: "JSON_INVALID",
2426
+ message: error?.message || `Invalid JSON in ${filePath}.`,
2427
+ file: filePath
2428
+ });
2429
+ return void 0;
2430
+ }
2431
+ }
2432
+ function validateCommonClaims(manifest, issues, filePath) {
2433
+ expectEqual(manifest.network, "simnet", issues, "NETWORK_INVALID", filePath);
2434
+ expectEqual(manifest.profile, "toccata-v2", issues, "PROFILE_INVALID", filePath);
2435
+ const claim = manifest.simulationClaim || manifest.simulationLevel;
2436
+ expectEqual(
2437
+ claim?.artifactCoherence,
2438
+ "READY",
2439
+ issues,
2440
+ "ARTIFACT_COHERENCE_CLAIM_INVALID",
2441
+ filePath
2442
+ );
2443
+ expectEqual(
2444
+ claim?.runtimeOutcome,
2445
+ "PARTIAL",
2446
+ issues,
2447
+ "RUNTIME_OUTCOME_CLAIM_INVALID",
2448
+ filePath
2449
+ );
2450
+ expectEqual(
2451
+ claim?.vmConsensusEquivalence,
2452
+ "NOT_CLAIMED",
2453
+ issues,
2454
+ "VM_CONSENSUS_CLAIM_INVALID",
2455
+ filePath
2456
+ );
2457
+ expectKnownLimitation(manifest, issues, filePath);
2458
+ }
2459
+ function expectKnownLimitation(value, issues, filePath) {
2460
+ const limitations = value.expectedKnownLimitations || [value.expectedCompareStatus].filter(Boolean);
2461
+ if (!Array.isArray(limitations) || !limitations.includes(EXPECTED_LIMITATION)) {
2462
+ issues.push({
2463
+ code: "PARTIAL_VM_SIMULATION_NOT_DECLARED",
2464
+ message: "Expected known limitations must include PARTIAL_VM_SIMULATION.",
2465
+ file: filePath
2466
+ });
2467
+ }
2468
+ }
2469
+ function verifyContentHash(artifact, issues, filePath) {
2470
+ if (typeof artifact.contentHash !== "string") {
2471
+ issues.push({
2472
+ code: "CONTENT_HASH_MISSING",
2473
+ message: "Artifact is missing contentHash.",
2474
+ file: filePath
2475
+ });
2476
+ return;
2477
+ }
2478
+ const actual = calculateContentHash2(artifact, artifact.hashVersion ?? 4);
2479
+ if (actual !== artifact.contentHash) {
2480
+ issues.push({
2481
+ code: "CONTENT_HASH_MISMATCH",
2482
+ message: `Expected ${artifact.contentHash}, got ${actual}.`,
2483
+ file: filePath
2484
+ });
2485
+ }
2486
+ }
2487
+ function validateFailureReferences(fixture, issues, filePath, corpusPath) {
2488
+ for (const ref of collectFixtureRefs(fixture)) {
2489
+ const refPath = ref.split("#")[0];
2490
+ if (!refPath) {
2491
+ issues.push({
2492
+ code: "FAILURE_REFERENCE_INVALID",
2493
+ message: `Referenced fixture path is empty: ${ref}.`,
2494
+ file: filePath
2495
+ });
2496
+ continue;
2497
+ }
2498
+ const resolved = path4.resolve(path4.dirname(filePath), refPath);
2499
+ if (!resolved.startsWith(corpusPath) || !fs4.existsSync(resolved)) {
2500
+ issues.push({
2501
+ code: "FAILURE_REFERENCE_INVALID",
2502
+ message: `Referenced fixture file does not exist or escapes corpus: ${ref}.`,
2503
+ file: filePath
2504
+ });
2505
+ }
2506
+ }
2507
+ }
2508
+ function collectFixtureRefs(fixture) {
2509
+ const refs = [fixture.baseArtifact, fixture.requiredState].filter(Boolean);
2510
+ const setupRefs = fixture.stateSetup ? [fixture.stateSetup.deployPlan, fixture.stateSetup.deploySimulationReceipt] : [];
2511
+ const normalizationRefs = fixture.stateSetup?.simulatorSpendInputNormalization ?? [];
2512
+ for (const entry of normalizationRefs) {
2513
+ if (entry.valueFrom) refs.push(entry.valueFrom);
2514
+ }
2515
+ return [...refs, ...setupRefs].filter(Boolean);
2516
+ }
2517
+ function validateMainnetGuard(entry, fixture, issues, filePath) {
2518
+ const status = fixture.expectedReal?.status;
2519
+ const error = fixture.expectedReal?.error || entry.expectedRealError;
2520
+ if (status !== "BLOCKED_BY_POLICY" || error !== "SILVERSCRIPT_MAINNET_NOT_ENABLED") {
2521
+ issues.push({
2522
+ code: "MAINNET_GUARD_CLAIM_INVALID",
2523
+ message: "mainnet-guard must declare BLOCKED_BY_POLICY / SILVERSCRIPT_MAINNET_NOT_ENABLED.",
2524
+ file: filePath
2525
+ });
2526
+ }
2527
+ }
2528
+ function collectKnownLimitations(...values) {
2529
+ return Array.from(
2530
+ new Set(
2531
+ values.flatMap((value) => {
2532
+ if (!value) return [];
2533
+ if (Array.isArray(value.expectedKnownLimitations))
2534
+ return value.expectedKnownLimitations;
2535
+ return [value.expectedCompareStatus].filter(Boolean);
2536
+ })
2537
+ )
2538
+ ).sort();
2539
+ }
2540
+ function expectEqual(actual, expected, issues, code, file) {
2541
+ if (actual !== expected) {
2542
+ issues.push({
2543
+ code,
2544
+ message: `Expected ${String(expected)}, got ${String(actual)}.`,
2545
+ file
2546
+ });
2547
+ }
2548
+ }
2549
+
2550
+ // src/silver.ts
2551
+ import { execFileSync as execFileSync2 } from "child_process";
2552
+ import { createHash } from "crypto";
2553
+ import fs5 from "fs";
2554
+ import path5 from "path";
2555
+ import { calculateContentHash as calculateContentHash3, HARDKAS_VERSION as HARDKAS_VERSION4, writeArtifact as writeArtifact3 } from "@hardkas/artifacts";
2556
+ import {
2557
+ createKaspaP2shBlake2bLock,
2558
+ createPushOnlySignatureScript,
2559
+ parseKasToSompi as parseKasToSompi2
2560
+ } from "@hardkas/core";
2561
+ import {
2562
+ createSilverSimulationState,
2563
+ simulateSilverDeploy,
2564
+ simulateSilverSpend
2565
+ } from "@hardkas/simulator";
2566
+ import { HardkasSchemas as HardkasSchemas6 } from "@hardkas/artifacts";
2567
+ var HardkasSilver = class {
2568
+ constructor(sdk) {
2569
+ this.sdk = sdk;
2570
+ }
2571
+ sdk;
2572
+ simulate = {
2573
+ deploy: (deployPlan, options = {}) => this.simulateDeploy(deployPlan, options),
2574
+ spend: (spendPlan, state = this.loadSimulationState(), options = {}) => this.simulateSpend(spendPlan, state, options),
2575
+ compare: (options) => this.compare(options)
2576
+ };
2577
+ async compile(options) {
2578
+ const network = options.network || "simnet";
2579
+ assertSimnet(network);
2580
+ const filePath = path5.resolve(this.sdk.cwd, options.file);
2581
+ if (!fs5.existsSync(filePath)) {
2582
+ throw new Error(`SILVERSCRIPT_SOURCE_NOT_FOUND: ${filePath}`);
2583
+ }
2584
+ const compilerPath = resolveCompilerPath(this.sdk.cwd, options.compilerPath);
2585
+ if (!isExecutableAvailable(compilerPath)) {
2586
+ throw new Error(
2587
+ "SILVERSCRIPT_COMPILER_UNAVAILABLE: pass compilerPath, set HARDKAS_SILVERC_PATH, or install .hardkas/bin/silverc."
2588
+ );
2589
+ }
2590
+ const sourceContent = fs5.readFileSync(filePath, "utf8");
2591
+ const compilerOutput = execFileSync2(compilerPath, [filePath, "-c"], {
2592
+ encoding: "utf8",
2593
+ stdio: "pipe"
2594
+ });
2595
+ const normalized = normalizeSilverCompilerOutput(compilerOutput);
2596
+ if (!normalized.scriptHex) {
2597
+ throw new Error(
2598
+ "SILVERSCRIPT_COMPILER_OUTPUT_INVALID: compiled script hex not found."
2599
+ );
2600
+ }
2601
+ const artifact = {
2602
+ schema: HardkasSchemas6.SilverCompile,
2603
+ hardkasVersion: HARDKAS_VERSION4,
2604
+ version: "1.0.0-alpha",
2605
+ hashVersion: 4,
2606
+ networkId: network,
2607
+ mode: "simulated",
2608
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
2609
+ sourcePath: filePath,
2610
+ sourceHash: createHash("sha256").update(sourceContent).digest("hex"),
2611
+ compilerName: "silverc",
2612
+ compilerVersion: "unknown",
2613
+ compilerCommand: `${compilerPath} "${filePath}" -c`,
2614
+ compiledScriptHex: normalized.scriptHex,
2615
+ compiledScriptHash: normalized.scriptHash || createHash("sha256").update(Buffer.from(normalized.scriptHex, "hex")).digest("hex"),
2616
+ abi: normalized.abi,
2617
+ network,
2618
+ assumptions: ["toccata-v2", "mainnet-disabled"]
2619
+ };
2620
+ finalizeArtifact(artifact, "silver");
2621
+ return this.writeSdkArtifact(artifact, options);
2622
+ }
2623
+ async deployPlan(options) {
2624
+ const network = options.network || "simnet";
2625
+ assertSimnet(network);
2626
+ const compileArtifact = await this.resolveArtifact(
2627
+ options.artifact,
2628
+ HardkasSchemas6.SilverCompile
2629
+ );
2630
+ const amountSompi = parseKasToSompi2(String(options.amount ?? "1")).toString();
2631
+ const fromAccount = await this.sdk.accounts.resolve(options.from);
2632
+ const lock = createKaspaP2shBlake2bLock(compileArtifact.compiledScriptHex);
2633
+ const artifact = {
2634
+ schema: HardkasSchemas6.SilverDeployPlan,
2635
+ hardkasVersion: HARDKAS_VERSION4,
2636
+ version: "1.0.0-alpha",
2637
+ hashVersion: 4,
2638
+ networkId: network,
2639
+ mode: "simulated",
2640
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
2641
+ compileArtifactHash: compileArtifact.contentHash,
2642
+ compiledScriptHash: compileArtifact.compiledScriptHash,
2643
+ redeemScriptHex: lock.redeemScriptHex,
2644
+ redeemScriptHash: lock.redeemScriptHash,
2645
+ lockingScriptHex: lock.lockingScriptHex,
2646
+ scriptPublicKeyVersion: lock.scriptPublicKeyVersion,
2647
+ amountSompi,
2648
+ deployerAddress: fromAccount.address
2649
+ };
2650
+ finalizeArtifact(artifact, "silverdeployplan");
2651
+ return this.writeSdkArtifact(artifact, options);
2652
+ }
2653
+ async deploy(options) {
2654
+ if (options.mode === "real") {
2655
+ throw new Error(
2656
+ "SDK_SILVER_REAL_LIFECYCLE_UNSUPPORTED: use `hardkas silver deploy` for Docker/RPC execution in 0.9.1-alpha."
2657
+ );
2658
+ }
2659
+ return this.simulateDeploy(options.artifact, options);
2660
+ }
2661
+ async spendPlan(options) {
2662
+ const deployArtifact = await this.resolveArtifact(
2663
+ options.receipt,
2664
+ HardkasSchemas6.SilverDeploy
2665
+ );
2666
+ assertSimnet(deployArtifact.networkId);
2667
+ const args = options.args ?? readArgsFile(this.sdk.cwd, options.argsPath);
2668
+ const lock = createKaspaP2shBlake2bLock(deployArtifact.redeemScriptHex);
2669
+ if (lock.lockingScriptHex !== deployArtifact.lockingScriptHex) {
2670
+ throw new Error("SILVERSCRIPT_LOCKING_SCRIPT_MISMATCH");
2671
+ }
2672
+ if (lock.redeemScriptHash !== deployArtifact.redeemScriptHash) {
2673
+ throw new Error("SILVERSCRIPT_REDEEM_HASH_MISMATCH");
2674
+ }
2675
+ const signatureScriptHex = createPushOnlySignatureScript(
2676
+ args.map((arg) => arg.value),
2677
+ lock.redeemScriptHex
2678
+ );
2679
+ const feeSompi = 200000n;
2680
+ const sendAmount = BigInt(deployArtifact.amountSompi) - feeSompi;
2681
+ if (sendAmount <= 0n) {
2682
+ throw new Error("SILVERSCRIPT_AMOUNT_TOO_SMALL");
2683
+ }
2684
+ const artifact = {
2685
+ schema: HardkasSchemas6.SilverSpendPlan,
2686
+ hardkasVersion: HARDKAS_VERSION4,
2687
+ version: "1.0.0-alpha",
2688
+ hashVersion: 4,
2689
+ networkId: deployArtifact.networkId,
2690
+ mode: "simulated",
2691
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
2692
+ deployArtifactHash: deployArtifact.contentHash,
2693
+ compileArtifactHash: deployArtifact.compileArtifactHash,
2694
+ redeemScriptHash: lock.redeemScriptHash,
2695
+ lockingScriptHex: lock.lockingScriptHex,
2696
+ contractUtxoRef: {
2697
+ transactionId: deployArtifact.deployTxId,
2698
+ index: deployArtifact.outputIndex
2699
+ },
2700
+ args,
2701
+ argsHash: calculateArgsHash(args),
2702
+ signatureScriptHex,
2703
+ expectedOutputs: [
2704
+ {
2705
+ address: options.to,
2706
+ amountSompi: sendAmount.toString()
2707
+ }
2708
+ ]
2709
+ };
2710
+ finalizeArtifact(artifact, "silverspendplan");
2711
+ return this.writeSdkArtifact(artifact, options);
2712
+ }
2713
+ async spend(options) {
2714
+ if (options.mode === "real") {
2715
+ throw new Error(
2716
+ "SDK_SILVER_REAL_LIFECYCLE_UNSUPPORTED: use `hardkas silver spend` for Docker/RPC execution in 0.9.1-alpha."
2717
+ );
2718
+ }
2719
+ return this.simulateSpend(
2720
+ options.artifact,
2721
+ options.state ?? this.loadSimulationState(),
2722
+ options
2723
+ );
2724
+ }
2725
+ async simulateDeploy(deployPlan, options = {}) {
2726
+ const artifact = await this.resolveArtifact(deployPlan, HardkasSchemas6.SilverDeployPlan);
2727
+ const result = simulateSilverDeploy(artifact);
2728
+ this.saveSimulationState(mergeState(this.loadSimulationState(), result.state));
2729
+ return this.writeSdkArtifact(result.receipt, options);
2730
+ }
2731
+ async simulateSpend(spendPlan, state = this.loadSimulationState(), options = {}) {
2732
+ const artifact = await this.resolveArtifact(spendPlan, HardkasSchemas6.SilverSpendPlan);
2733
+ const result = simulateSilverSpend(artifact, state);
2734
+ this.saveSimulationState(result.state);
2735
+ return this.writeSdkArtifact(result.receipt, options);
2736
+ }
2737
+ async compare(options) {
2738
+ const simulated = await this.resolveArtifact(options.simulated);
2739
+ const docker = await this.resolveArtifact(options.docker);
2740
+ const mode = normalizeCompareMode(options.mode || "artifact-coherence");
2741
+ const { drift, notes } = compareSilverReceipts(simulated, docker, mode);
2742
+ return {
2743
+ status: drift.length === 0 ? "SILVERSCRIPT_SIMULATION_MATCH" : "SILVERSCRIPT_SIMULATION_DRIFT",
2744
+ mode,
2745
+ drift,
2746
+ notes,
2747
+ expectedKnownLimitations: ["PARTIAL_VM_SIMULATION"]
2748
+ };
2749
+ }
2750
+ async resolveArtifact(target, expectedSchema) {
2751
+ const artifact = typeof target === "string" ? await this.sdk.artifacts.read(target) : target;
2752
+ if (expectedSchema && artifact.schema !== expectedSchema) {
2753
+ throw new Error(
2754
+ `SILVERSCRIPT_SCHEMA_INVALID: expected ${expectedSchema}, got ${artifact.schema}.`
2755
+ );
2756
+ }
2757
+ return artifact;
2758
+ }
2759
+ async writeSdkArtifact(artifact, options) {
2760
+ if (options.write === false) return { artifact };
2761
+ const artifactPath = options.outputPath ? path5.resolve(this.sdk.cwd, options.outputPath) : path5.join(this.sdk.cwd, `${artifact.artifactId}.json`);
2762
+ await writeArtifact3(artifactPath, artifact);
2763
+ this.sdk.artifacts.cacheArtifact(artifact);
2764
+ return { artifact, artifactPath };
2765
+ }
2766
+ simulationStatePath() {
2767
+ return path5.join(this.sdk.workspace.hardkasDir, "silver-simulator", "state.json");
2768
+ }
2769
+ loadSimulationState() {
2770
+ const statePath = this.simulationStatePath();
2771
+ if (!fs5.existsSync(statePath)) return createSilverSimulationState();
2772
+ return JSON.parse(fs5.readFileSync(statePath, "utf8"));
2773
+ }
2774
+ saveSimulationState(state) {
2775
+ const statePath = this.simulationStatePath();
2776
+ fs5.mkdirSync(path5.dirname(statePath), { recursive: true });
2777
+ fs5.writeFileSync(statePath, `${JSON.stringify(state, null, 2)}
2778
+ `, "utf8");
2779
+ }
2780
+ };
2781
+ function assertSimnet(network) {
2782
+ if (network !== "simnet") {
2783
+ throw new Error(
2784
+ "SILVERSCRIPT_MAINNET_NOT_ENABLED: Only simnet is supported for SilverScript lifecycle."
2785
+ );
2786
+ }
2787
+ }
2788
+ function resolveCompilerPath(cwd, explicit) {
2789
+ return explicit || process.env.HARDKAS_SILVERC_PATH || path5.join(
2790
+ cwd,
2791
+ ".hardkas",
2792
+ "bin",
2793
+ process.platform === "win32" ? "silverc.exe" : "silverc"
2794
+ );
2795
+ }
2796
+ function isExecutableAvailable(command) {
2797
+ try {
2798
+ execFileSync2(command, ["--help"], { stdio: "ignore" });
2799
+ return true;
2800
+ } catch {
2801
+ return fs5.existsSync(command);
2802
+ }
2803
+ }
2804
+ function normalizeSilverCompilerOutput(rawOutput) {
2805
+ const normalized = {};
2806
+ const hexMatch = rawOutput.match(/Compiled script:\s*([a-fA-F0-9]+)/i);
2807
+ if (hexMatch?.[1]) normalized.scriptHex = hexMatch[1];
2808
+ const hashMatch = rawOutput.match(/Script Hash:\s*([a-fA-F0-9]+)/i);
2809
+ if (hashMatch?.[1]) normalized.scriptHash = hashMatch[1];
2810
+ try {
2811
+ const parsed = JSON.parse(rawOutput);
2812
+ if (Array.isArray(parsed.script)) {
2813
+ normalized.scriptHex = Buffer.from(parsed.script).toString("hex");
2814
+ } else if (typeof parsed.scriptHex === "string") {
2815
+ normalized.scriptHex = parsed.scriptHex;
2816
+ }
2817
+ if (typeof parsed.scriptHash === "string") normalized.scriptHash = parsed.scriptHash;
2818
+ if (parsed.abi !== void 0) normalized.abi = parsed.abi;
2819
+ } catch {
2820
+ }
2821
+ return normalized;
2822
+ }
2823
+ function readArgsFile(cwd, argsPath) {
2824
+ if (!argsPath) return [];
2825
+ const parsed = JSON.parse(fs5.readFileSync(path5.resolve(cwd, argsPath), "utf8"));
2826
+ const args = parsed.args ?? parsed;
2827
+ if (!Array.isArray(args))
2828
+ throw new Error("SILVERSCRIPT_SPEND_PLAN_INVALID: args must be an array.");
2829
+ return args.map((arg) => {
2830
+ if (arg.type !== "hex" || typeof arg.value !== "string") {
2831
+ throw new Error(
2832
+ "SILVERSCRIPT_SPEND_PLAN_INVALID: args must be { type: 'hex', value }."
2833
+ );
2834
+ }
2835
+ return { type: "hex", value: arg.value };
2836
+ });
2837
+ }
2838
+ function calculateArgsHash(args) {
2839
+ return createHash("sha256").update(JSON.stringify(args)).digest("hex");
2840
+ }
2841
+ function finalizeArtifact(artifact, prefix) {
2842
+ artifact.contentHash = calculateContentHash3(artifact);
2843
+ artifact.artifactId = `${prefix}-${artifact.contentHash.substring(0, 16)}`;
2844
+ }
2845
+ function mergeState(existing, next) {
2846
+ return {
2847
+ ...next,
2848
+ deployReceipts: {
2849
+ ...existing.deployReceipts,
2850
+ ...next.deployReceipts
2851
+ },
2852
+ utxos: {
2853
+ ...existing.utxos,
2854
+ ...next.utxos
2855
+ },
2856
+ spentOutpoints: Array.from(
2857
+ /* @__PURE__ */ new Set([...existing.spentOutpoints, ...next.spentOutpoints])
2858
+ ).sort()
2859
+ };
2860
+ }
2861
+ function normalizeCompareMode(mode) {
2862
+ if (mode === "artifact-coherence" || mode === "runtime-outcome" || mode === "strict")
2863
+ return mode;
2864
+ throw new Error(
2865
+ "SILVERSCRIPT_COMPARE_MODE_INVALID: Expected artifact-coherence, runtime-outcome, or strict."
2866
+ );
2867
+ }
2868
+ function stableJson(value) {
2869
+ if (value === null || typeof value !== "object") return JSON.stringify(value);
2870
+ if (Array.isArray(value)) return `[${value.map(stableJson).join(",")}]`;
2871
+ const record = value;
2872
+ return `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${stableJson(record[key])}`).join(",")}}`;
2873
+ }
2874
+ function valuesMatch(field, simulated, docker) {
2875
+ if (field === "status") {
2876
+ return simulated === docker || simulated === "SIMULATED_ACCEPTED" && (docker === "accepted" || docker === "submitted");
2877
+ }
2878
+ return stableJson(simulated) === stableJson(docker);
2879
+ }
2880
+ function compareSilverReceipts(simulated, docker, mode) {
2881
+ const drift = [];
2882
+ const notes = [];
2883
+ const fields = [
2884
+ "redeemScriptHash",
2885
+ "lockingScriptHex",
2886
+ "signatureScriptHex",
2887
+ "expectedOutputs",
2888
+ "status"
2889
+ ];
2890
+ if (mode === "runtime-outcome" || mode === "strict")
2891
+ fields.push("networkId", "spentOutpoint");
2892
+ if (mode === "strict") fields.push("lineage", "txId", "simulatedSpendTxId");
2893
+ for (const field of fields) {
2894
+ const entry = compareField(field, simulated[field], docker[field]);
2895
+ if (entry.classification === "MATCH") continue;
2896
+ const nonConsensusRuntimeIds = mode === "runtime-outcome" && (field === "spentOutpoint" || field === "txId" || field === "simulatedSpendTxId");
2897
+ if (nonConsensusRuntimeIds) {
2898
+ notes.push({
2899
+ ...entry,
2900
+ classification: "SEMANTICALLY_DERIVED",
2901
+ reason: "synthetic simulator runtime identifier differs from Docker-observed runtime identifier"
2902
+ });
2903
+ continue;
2904
+ }
2905
+ drift.push(entry);
2906
+ }
2907
+ if (mode !== "strict") {
2908
+ const lineageReport = compareLineageSemantics(simulated, docker, mode);
2909
+ drift.push(...lineageReport.drift);
2910
+ notes.push(...lineageReport.notes);
2911
+ }
2912
+ return { drift, notes };
2913
+ }
2914
+ function compareField(field, simulatedValue, dockerValue) {
2915
+ if (simulatedValue === void 0) {
2916
+ return {
2917
+ field,
2918
+ reason: "missing in simulated receipt",
2919
+ classification: "MISSING_IN_SIM"
2920
+ };
2921
+ }
2922
+ if (dockerValue === void 0) {
2923
+ return {
2924
+ field,
2925
+ reason: "missing in docker receipt",
2926
+ classification: "MISSING_IN_REAL"
2927
+ };
2928
+ }
2929
+ if (valuesMatch(field, simulatedValue, dockerValue)) {
2930
+ return { field, reason: "match", classification: "MATCH" };
2931
+ }
2932
+ return { field, reason: "semantic mismatch", classification: "SEMANTIC_MISMATCH" };
2933
+ }
2934
+ function compareLineageSemantics(simulated, docker, mode) {
2935
+ const drift = [];
2936
+ const notes = [];
2937
+ if (!simulated.lineage) {
2938
+ drift.push({
2939
+ field: "lineage",
2940
+ reason: "missing in simulated receipt",
2941
+ classification: "MISSING_IN_SIM"
2942
+ });
2943
+ return { drift, notes };
2944
+ }
2945
+ if (!docker.lineage) {
2946
+ drift.push({
2947
+ field: "lineage",
2948
+ reason: "missing in docker receipt",
2949
+ classification: "MISSING_IN_REAL"
2950
+ });
2951
+ return { drift, notes };
2952
+ }
2953
+ for (const check of [
2954
+ [
2955
+ "lineage.redeemScriptHash",
2956
+ simulated.redeemScriptHash,
2957
+ docker.redeemScriptHash,
2958
+ "redeem script hash anchors artifact coherence"
2959
+ ],
2960
+ [
2961
+ "lineage.lockingScriptHex",
2962
+ simulated.lockingScriptHex,
2963
+ docker.lockingScriptHex,
2964
+ "locking script anchors artifact coherence"
2965
+ ],
2966
+ [
2967
+ "lineage.signatureScriptHex",
2968
+ simulated.signatureScriptHex,
2969
+ docker.signatureScriptHex,
2970
+ "unlock script anchors artifact coherence"
2971
+ ],
2972
+ [
2973
+ "lineage.expectedOutputs",
2974
+ simulated.expectedOutputs,
2975
+ docker.expectedOutputs,
2976
+ "expected outputs anchor artifact coherence"
2977
+ ],
2978
+ ["lineage.network", simulated.networkId, docker.networkId, "network must match"]
2979
+ ]) {
2980
+ const entry = compareField(check[0], check[1], check[2]);
2981
+ if (entry.classification !== "MATCH") drift.push({ ...entry, reason: check[3] });
2982
+ }
2983
+ notes.push({
2984
+ field: "lineage.blob",
2985
+ reason: mode === "artifact-coherence" ? "raw lineage IDs are domain-specific: simulator lineage is synthetic, Docker lineage is receipt artifact lineage" : "raw lineage IDs are compared by semantic anchors; VM/consensus lineage equivalence is not claimed",
2986
+ classification: "SEMANTICALLY_DERIVED"
2987
+ });
2988
+ if (simulated.simulatedSpendTxId || docker.txId) {
2989
+ notes.push({
2990
+ field: "lineage.runtime.txid",
2991
+ reason: "simulatedSpendTxId and Docker txId are intentionally different runtime identifiers",
2992
+ classification: "IGNORED_NON_CONSENSUS"
2993
+ });
2994
+ }
2995
+ return { drift, notes };
2996
+ }
2997
+
2998
+ // src/zk.ts
2999
+ import fs6 from "fs";
3000
+ import path6 from "path";
3001
+ import { calculateContentHash as calculateContentHash4 } from "@hardkas/artifacts";
3002
+ import { HardkasSchemas as HardkasSchemas7 } from "@hardkas/artifacts";
3003
+ var ZK_KNOWN_LIMITATIONS = [
3004
+ "ZK_ONCHAIN_VERIFICATION_NOT_CLAIMED",
3005
+ "PARTIAL_VM_SIMULATION"
3006
+ ];
3007
+ var HardkasZk = class {
3008
+ constructor(sdk) {
3009
+ this.sdk = sdk;
3010
+ this.proof = {
3011
+ inspect: (targetPath) => inspectZkProof(targetPath, this.sdk.cwd),
3012
+ verifyLocal: (targetPath) => verifyZkProofLocal(targetPath, this.sdk.cwd)
3013
+ };
3014
+ this.corpus = {
3015
+ verify: (targetPath) => verifyZkCorpus(targetPath, this.sdk.cwd)
3016
+ };
3017
+ }
3018
+ sdk;
3019
+ proof;
3020
+ corpus;
3021
+ async capabilities() {
3022
+ return createZkCapabilities();
3023
+ }
3024
+ };
3025
+ function createZkCapabilities() {
3026
+ return {
3027
+ schema: HardkasSchemas7.ZkCapabilitiesV1,
3028
+ experimental: true,
3029
+ proofSystems: {
3030
+ groth16: {
3031
+ inspect: true,
3032
+ verifyLocal: "FIXTURE_COHERENCE_ONLY",
3033
+ proofGeneration: "NOT_CLAIMED"
3034
+ },
3035
+ risc0: {
3036
+ inspect: true,
3037
+ verifyLocal: "RISC0_LOCAL_VERIFICATION_NOT_IMPLEMENTED",
3038
+ proofGeneration: "NOT_CLAIMED"
3039
+ }
3040
+ },
3041
+ claims: zkClaims(),
3042
+ errors: [
3043
+ "SDK_ZK_ONCHAIN_VERIFICATION_UNSUPPORTED",
3044
+ "ZK_ONCHAIN_VERIFICATION_NOT_CLAIMED",
3045
+ "ZK_VERIFIER_UNSUPPORTED",
3046
+ "ZK_VERIFIER_UNAVAILABLE",
3047
+ "ZK_CORPUS_MANIFEST_INVALID",
3048
+ "ZK_CORPUS_HASH_MISMATCH",
3049
+ "RISC0_VERIFIER_UNAVAILABLE",
3050
+ "RISC0_LOCAL_VERIFICATION_NOT_IMPLEMENTED"
3051
+ ]
3052
+ };
3053
+ }
3054
+ async function inspectZkProof(targetPath, workspaceRoot = process.cwd()) {
3055
+ const resolved = path6.resolve(workspaceRoot, targetPath);
3056
+ const issues = [];
3057
+ const manifestPath = resolveManifestPath(resolved, issues);
3058
+ const manifest = manifestPath ? readJson(manifestPath, issues) : void 0;
3059
+ const dir = manifestPath ? path6.dirname(manifestPath) : path6.dirname(resolved);
3060
+ const proofSystem = detectProofSystem(manifest, resolved);
3061
+ const fixtureFiles = collectFixtureFiles(manifest);
3062
+ const files = fixtureFiles.map((entry) => entry.file);
3063
+ const contentHashes = {};
3064
+ for (const { key, file } of fixtureFiles) {
3065
+ const filePath = path6.join(dir, file);
3066
+ const value = readJson(filePath, issues);
3067
+ if (!value) continue;
3068
+ const actual = calculateContentHash4(value);
3069
+ contentHashes[file] = actual;
3070
+ const expected = manifest?.contentHashes?.[key];
3071
+ if (typeof expected === "string" && expected !== actual) {
3072
+ issues.push({
3073
+ code: "ZK_CORPUS_HASH_MISMATCH",
3074
+ message: `Expected ${expected}, got ${actual}.`,
3075
+ file: filePath
3076
+ });
3077
+ }
3078
+ }
3079
+ const ok = issues.length === 0 && proofSystem !== "unknown";
3080
+ if (proofSystem === "unknown") {
3081
+ issues.push({
3082
+ code: "ZK_VERIFIER_UNSUPPORTED",
3083
+ message: "Could not determine proof system from artifact or manifest.",
3084
+ file: resolved
3085
+ });
3086
+ }
3087
+ return {
3088
+ ok,
3089
+ schema: HardkasSchemas7.ZkProofInspectV1,
3090
+ path: path6.relative(workspaceRoot, resolved).replace(/\\/g, "/"),
3091
+ proofSystem,
3092
+ status: ok ? "ZK_PROOF_INSPECTED" : "ZK_PROOF_INSPECT_FAILED",
3093
+ experimental: true,
3094
+ summary: {
3095
+ files,
3096
+ contentHashes,
3097
+ verifierAdapter: manifest?.verifierAdapter,
3098
+ expectedStatus: manifest?.expectedStatus
3099
+ },
3100
+ claims: zkClaims(),
3101
+ issues
3102
+ };
3103
+ }
3104
+ async function verifyZkProofLocal(targetPath, workspaceRoot = process.cwd()) {
3105
+ const resolved = path6.resolve(workspaceRoot, targetPath);
3106
+ const issues = [];
3107
+ const manifestPath = resolveManifestPath(resolved, issues);
3108
+ const manifest = manifestPath ? readJson(manifestPath, issues) : void 0;
3109
+ const dir = manifestPath ? path6.dirname(manifestPath) : path6.dirname(resolved);
3110
+ const proofSystem = detectProofSystem(manifest, resolved);
3111
+ if (proofSystem === "risc0") {
3112
+ return {
3113
+ ok: false,
3114
+ schema: HardkasSchemas7.ZkProofVerificationV1,
3115
+ path: path6.relative(workspaceRoot, resolved).replace(/\\/g, "/"),
3116
+ proofSystem,
3117
+ status: "RISC0_LOCAL_VERIFICATION_NOT_IMPLEMENTED",
3118
+ experimental: true,
3119
+ summary: {
3120
+ verifierAdapter: manifest?.verifierAdapter ?? "risc0-helper",
3121
+ contentHashes: "PASS",
3122
+ localVerification: "NOT_IMPLEMENTED"
3123
+ },
3124
+ claims: zkClaims(),
3125
+ issues: [
3126
+ {
3127
+ code: "RISC0_VERIFIER_UNAVAILABLE",
3128
+ message: "RISC0 local receipt verification helper is not bundled in 0.9.1-alpha."
3129
+ },
3130
+ {
3131
+ code: "RISC0_LOCAL_VERIFICATION_NOT_IMPLEMENTED",
3132
+ message: "RISC0 is inspect-only in this experimental lab scaffold."
3133
+ }
3134
+ ]
3135
+ };
3136
+ }
3137
+ if (proofSystem !== "groth16") {
3138
+ return unsupportedVerification(
3139
+ resolved,
3140
+ workspaceRoot,
3141
+ proofSystem,
3142
+ issues,
3143
+ manifest?.verifierAdapter
3144
+ );
3145
+ }
3146
+ verifyGroth16Fixture(dir, manifest, issues);
3147
+ const ok = issues.length === 0;
3148
+ return {
3149
+ ok,
3150
+ schema: HardkasSchemas7.ZkProofVerificationV1,
3151
+ path: path6.relative(workspaceRoot, resolved).replace(/\\/g, "/"),
3152
+ proofSystem,
3153
+ status: ok ? "ZK_FIXTURE_COHERENCE_PASS" : "ZK_FIXTURE_COHERENCE_FAIL",
3154
+ experimental: true,
3155
+ summary: {
3156
+ verifierAdapter: manifest?.verifierAdapter ?? "hardkas-groth16-fixture-coherence-v1",
3157
+ contentHashes: issues.some((issue) => issue.code.includes("HASH")) ? "FAIL" : "PASS",
3158
+ localVerification: ok ? "PASS" : "FAIL"
3159
+ },
3160
+ claims: zkClaims(),
3161
+ issues
3162
+ };
3163
+ }
3164
+ async function verifyZkCorpus(targetPath, workspaceRoot = process.cwd()) {
3165
+ const corpusPath = path6.resolve(workspaceRoot, targetPath);
3166
+ const issues = [];
3167
+ const manifestPath = path6.join(corpusPath, "manifest.json");
3168
+ const manifest = readJson(manifestPath, issues);
3169
+ if (manifest) {
3170
+ expectEqual2(
3171
+ manifest.schema,
3172
+ HardkasSchemas7.ZkCorpusV1,
3173
+ issues,
3174
+ "ZK_CORPUS_MANIFEST_INVALID",
3175
+ manifestPath
3176
+ );
3177
+ expectEqual2(
3178
+ manifest.network,
3179
+ "simnet",
3180
+ issues,
3181
+ "ZK_NETWORK_UNSUPPORTED",
3182
+ manifestPath
3183
+ );
3184
+ expectEqual2(
3185
+ manifest.profile,
3186
+ "toccata-v2",
3187
+ issues,
3188
+ "ZK_PROFILE_UNSUPPORTED",
3189
+ manifestPath
3190
+ );
3191
+ expectEqual2(
3192
+ manifest.claims?.zkOnchainVerification,
3193
+ "NOT_CLAIMED",
3194
+ issues,
3195
+ "ZK_ONCHAIN_VERIFICATION_NOT_CLAIMED",
3196
+ manifestPath
3197
+ );
3198
+ expectEqual2(
3199
+ manifest.claims?.vmConsensusEquivalence,
3200
+ "NOT_CLAIMED",
3201
+ issues,
3202
+ "ZK_VM_CONSENSUS_CLAIM_INVALID",
3203
+ manifestPath
3204
+ );
3205
+ expectEqual2(
3206
+ manifest.claims?.mainnet,
3207
+ "BLOCKED_BY_POLICY",
3208
+ issues,
3209
+ "ZK_MAINNET_GUARD_INVALID",
3210
+ manifestPath
3211
+ );
3212
+ for (const limitation of ZK_KNOWN_LIMITATIONS) {
3213
+ if (!Array.isArray(manifest.expectedKnownLimitations) || !manifest.expectedKnownLimitations.includes(limitation)) {
3214
+ issues.push({
3215
+ code: "ZK_LIMITATION_NOT_DECLARED",
3216
+ message: `ZK corpus must declare ${limitation}.`,
3217
+ file: manifestPath
3218
+ });
3219
+ }
3220
+ }
3221
+ }
3222
+ let fixturesChecked = 0;
3223
+ let artifactsChecked = 0;
3224
+ const proofSystems = /* @__PURE__ */ new Set();
3225
+ if (Array.isArray(manifest?.fixtures)) {
3226
+ for (const fixture of manifest.fixtures) {
3227
+ fixturesChecked += 1;
3228
+ const fixturePath = path6.join(corpusPath, fixture.path);
3229
+ const inspect = await inspectZkProof(fixturePath, workspaceRoot);
3230
+ artifactsChecked += inspect.summary.files.length;
3231
+ if (inspect.proofSystem !== "unknown") proofSystems.add(inspect.proofSystem);
3232
+ issues.push(...inspect.issues);
3233
+ if (inspect.proofSystem === "groth16") {
3234
+ const verified = await verifyZkProofLocal(fixturePath, workspaceRoot);
3235
+ issues.push(...verified.issues);
3236
+ expectEqual2(
3237
+ verified.status,
3238
+ fixture.expectedStatus,
3239
+ issues,
3240
+ "ZK_FIXTURE_STATUS_MISMATCH",
3241
+ fixturePath
3242
+ );
3243
+ } else if (inspect.proofSystem === "risc0") {
3244
+ const verified = await verifyZkProofLocal(fixturePath, workspaceRoot);
3245
+ expectEqual2(
3246
+ verified.status,
3247
+ fixture.expectedStatus,
3248
+ issues,
3249
+ "ZK_FIXTURE_STATUS_MISMATCH",
3250
+ fixturePath
3251
+ );
3252
+ }
3253
+ }
3254
+ } else if (manifest) {
3255
+ issues.push({
3256
+ code: "ZK_CORPUS_MANIFEST_INVALID",
3257
+ message: "ZK corpus manifest must include fixtures array.",
3258
+ file: manifestPath
3259
+ });
3260
+ }
3261
+ const ok = issues.length === 0;
3262
+ return {
3263
+ ok,
3264
+ schema: HardkasSchemas7.ZkCorpusVerificationV1,
3265
+ path: path6.relative(workspaceRoot, corpusPath).replace(/\\/g, "/"),
3266
+ experimental: true,
3267
+ status: ok ? "ZK_CORPUS_VERIFICATION_PASS" : "ZK_CORPUS_VERIFICATION_FAIL",
3268
+ summary: {
3269
+ proofSystems: Array.from(proofSystems).sort(),
3270
+ fixturesChecked,
3271
+ artifactsChecked,
3272
+ contentHashes: issues.some((issue) => issue.code.includes("HASH")) ? "FAIL" : "PASS",
3273
+ localVerification: ok ? "PARTIAL" : "FAIL",
3274
+ knownLimitations: Array.isArray(manifest?.expectedKnownLimitations) ? manifest.expectedKnownLimitations : []
3275
+ },
3276
+ claims: {
3277
+ zkArtifactCoherence: ok ? "READY_MATCH" : "INVALID",
3278
+ zkLocalVerification: ok ? "READY_GROTH16_FIXTURE_COHERENCE" : "INVALID",
3279
+ zkOnchainVerification: ok ? "NOT_CLAIMED" : "INVALID",
3280
+ runtimeOutcome: ok ? "PARTIAL" : "INVALID",
3281
+ vmConsensusEquivalence: ok ? "NOT_CLAIMED" : "INVALID",
3282
+ mainnet: ok ? "BLOCKED_BY_POLICY" : "INVALID"
3283
+ },
3284
+ issues
3285
+ };
3286
+ }
3287
+ function verifyGroth16Fixture(dir, manifest, issues) {
3288
+ if (!manifest) return;
3289
+ const proofPath = path6.join(dir, manifest.proof ?? "proof.json");
3290
+ const inputsPath = path6.join(dir, manifest.publicInputs ?? "public-inputs.json");
3291
+ const keyPath = path6.join(dir, manifest.verificationKey ?? "verification-key.json");
3292
+ const metadataPath = path6.join(
3293
+ dir,
3294
+ manifest.verifierMetadata ?? "verifier-metadata.json"
3295
+ );
3296
+ const reportPath = path6.join(dir, manifest.verifyReport ?? "verify-report.json");
3297
+ const proof = readJson(proofPath, issues);
3298
+ const publicInputs = readJson(inputsPath, issues);
3299
+ const verificationKey = readJson(keyPath, issues);
3300
+ const metadata = readJson(metadataPath, issues);
3301
+ const report = readJson(reportPath, issues);
3302
+ if (!proof || !publicInputs || !verificationKey || !metadata || !report) return;
3303
+ verifyManifestHash(manifest, "proof", proof, issues, proofPath);
3304
+ verifyManifestHash(manifest, "publicInputs", publicInputs, issues, inputsPath);
3305
+ verifyManifestHash(manifest, "verificationKey", verificationKey, issues, keyPath);
3306
+ verifyManifestHash(manifest, "verifierMetadata", metadata, issues, metadataPath);
3307
+ verifyManifestHash(manifest, "verifyReport", report, issues, reportPath);
3308
+ const publicInputsHash = calculateContentHash4(publicInputs);
3309
+ const verificationKeyHash = calculateContentHash4(verificationKey);
3310
+ const proofHash = calculateContentHash4(proof);
3311
+ expectEqual2(
3312
+ proof.publicInputsHash,
3313
+ publicInputsHash,
3314
+ issues,
3315
+ "ZK_GROTH16_PUBLIC_INPUTS_HASH_MISMATCH",
3316
+ proofPath
3317
+ );
3318
+ expectEqual2(
3319
+ proof.verificationKeyHash,
3320
+ verificationKeyHash,
3321
+ issues,
3322
+ "ZK_GROTH16_VERIFICATION_KEY_HASH_MISMATCH",
3323
+ proofPath
3324
+ );
3325
+ expectEqual2(
3326
+ metadata.proofHash,
3327
+ proofHash,
3328
+ issues,
3329
+ "ZK_GROTH16_PROOF_HASH_MISMATCH",
3330
+ metadataPath
3331
+ );
3332
+ expectEqual2(
3333
+ metadata.publicInputsHash,
3334
+ publicInputsHash,
3335
+ issues,
3336
+ "ZK_GROTH16_PUBLIC_INPUTS_HASH_MISMATCH",
3337
+ metadataPath
3338
+ );
3339
+ expectEqual2(
3340
+ metadata.verificationKeyHash,
3341
+ verificationKeyHash,
3342
+ issues,
3343
+ "ZK_GROTH16_VERIFICATION_KEY_HASH_MISMATCH",
3344
+ metadataPath
3345
+ );
3346
+ expectEqual2(
3347
+ report.status,
3348
+ "ZK_FIXTURE_COHERENCE_PASS",
3349
+ issues,
3350
+ "ZK_GROTH16_REPORT_STATUS_INVALID",
3351
+ reportPath
3352
+ );
3353
+ expectEqual2(
3354
+ report.claims?.zkOnchainVerification,
3355
+ "NOT_CLAIMED",
3356
+ issues,
3357
+ "ZK_ONCHAIN_VERIFICATION_NOT_CLAIMED",
3358
+ reportPath
3359
+ );
3360
+ const coherenceDigest = calculateContentHash4({
3361
+ proofSystem: "groth16",
3362
+ proofHash,
3363
+ publicInputsHash,
3364
+ verificationKeyHash,
3365
+ statementHash: publicInputs.statementHash,
3366
+ verifierAdapter: manifest.verifierAdapter
3367
+ });
3368
+ expectEqual2(
3369
+ metadata.coherenceDigest,
3370
+ coherenceDigest,
3371
+ issues,
3372
+ "ZK_GROTH16_COHERENCE_MISMATCH",
3373
+ metadataPath
3374
+ );
3375
+ expectEqual2(
3376
+ report.coherenceDigest,
3377
+ coherenceDigest,
3378
+ issues,
3379
+ "ZK_GROTH16_COHERENCE_MISMATCH",
3380
+ reportPath
3381
+ );
3382
+ }
3383
+ function unsupportedVerification(resolved, workspaceRoot, proofSystem, issues, verifierAdapter) {
3384
+ return {
3385
+ ok: false,
3386
+ schema: HardkasSchemas7.ZkProofVerificationV1,
3387
+ path: path6.relative(workspaceRoot, resolved).replace(/\\/g, "/"),
3388
+ proofSystem,
3389
+ status: "ZK_VERIFIER_UNSUPPORTED",
3390
+ experimental: true,
3391
+ summary: {
3392
+ ...verifierAdapter ? { verifierAdapter } : {},
3393
+ contentHashes: issues.some((issue) => issue.code.includes("HASH")) ? "FAIL" : "PASS",
3394
+ localVerification: "FAIL"
3395
+ },
3396
+ claims: zkClaims(),
3397
+ issues: [
3398
+ ...issues,
3399
+ {
3400
+ code: "ZK_VERIFIER_UNSUPPORTED",
3401
+ message: `No local verifier is available for proof system ${proofSystem}.`
3402
+ }
3403
+ ]
3404
+ };
3405
+ }
3406
+ function resolveManifestPath(resolved, issues) {
3407
+ if (!fs6.existsSync(resolved)) {
3408
+ issues.push({
3409
+ code: "ZK_PROOF_FILE_MISSING",
3410
+ message: `Missing ${resolved}.`,
3411
+ file: resolved
3412
+ });
3413
+ return void 0;
3414
+ }
3415
+ const stat = fs6.statSync(resolved);
3416
+ if (stat.isDirectory()) return path6.join(resolved, "manifest.json");
3417
+ return resolved;
3418
+ }
3419
+ function collectFixtureFiles(manifest) {
3420
+ if (!manifest) return [];
3421
+ return [
3422
+ ["proof", manifest.proof],
3423
+ ["publicInputs", manifest.publicInputs],
3424
+ ["verificationKey", manifest.verificationKey],
3425
+ ["verifierMetadata", manifest.verifierMetadata],
3426
+ ["verifyReport", manifest.verifyReport],
3427
+ ["receipt", manifest.receipt],
3428
+ ["journal", manifest.journal],
3429
+ ["imageId", manifest.imageId]
3430
+ ].filter((entry) => typeof entry[1] === "string").map(([key, file]) => ({ key, file }));
3431
+ }
3432
+ function detectProofSystem(manifest, resolved) {
3433
+ const declared = manifest?.proofSystem;
3434
+ if (declared === "groth16" || declared === "risc0") return declared;
3435
+ const lower = resolved.toLowerCase();
3436
+ if (lower.includes("groth16")) return "groth16";
3437
+ if (lower.includes("risc0")) return "risc0";
3438
+ return "unknown";
3439
+ }
3440
+ function verifyManifestHash(manifest, key, value, issues, filePath) {
3441
+ const expected = manifest.contentHashes?.[key];
3442
+ if (typeof expected !== "string") {
3443
+ issues.push({
3444
+ code: "ZK_CORPUS_HASH_MISSING",
3445
+ message: `Missing content hash for ${key}.`,
3446
+ file: filePath
3447
+ });
3448
+ return;
3449
+ }
3450
+ const actual = calculateContentHash4(value);
3451
+ if (actual !== expected) {
3452
+ issues.push({
3453
+ code: "ZK_CORPUS_HASH_MISMATCH",
3454
+ message: `Expected ${expected}, got ${actual}.`,
3455
+ file: filePath
3456
+ });
3457
+ }
3458
+ }
3459
+ function readJson(filePath, issues) {
3460
+ if (!fs6.existsSync(filePath)) {
3461
+ issues.push({
3462
+ code: "ZK_FILE_MISSING",
3463
+ message: `Missing ${filePath}.`,
3464
+ file: filePath
3465
+ });
3466
+ return void 0;
3467
+ }
3468
+ try {
3469
+ return JSON.parse(fs6.readFileSync(filePath, "utf8"));
3470
+ } catch (error) {
3471
+ issues.push({
3472
+ code: "ZK_JSON_INVALID",
3473
+ message: error?.message || `Invalid JSON in ${filePath}.`,
3474
+ file: filePath
3475
+ });
3476
+ return void 0;
3477
+ }
3478
+ }
3479
+ function expectEqual2(actual, expected, issues, code, file) {
3480
+ if (actual !== expected) {
3481
+ issues.push({
3482
+ code,
3483
+ message: `Expected ${String(expected)}, got ${String(actual)}.`,
3484
+ file
3485
+ });
3486
+ }
3487
+ }
3488
+ function zkClaims() {
3489
+ return {
3490
+ zkArtifactCoherence: "EXPERIMENTAL",
3491
+ zkLocalVerification: "EXPERIMENTAL_FIXTURE_ONLY",
3492
+ zkOnchainVerification: "NOT_CLAIMED",
3493
+ vmConsensusEquivalence: "NOT_CLAIMED",
3494
+ mainnet: "BLOCKED_BY_POLICY"
3495
+ };
3496
+ }
3497
+
3498
+ // src/vprogs.ts
3499
+ import fs7 from "fs";
3500
+ import path7 from "path";
3501
+ import { calculateContentHash as calculateContentHash5 } from "@hardkas/artifacts";
3502
+ import { HardkasSchemas as HardkasSchemas8 } from "@hardkas/artifacts";
3503
+ var HardkasVprogs = class {
3504
+ constructor(sdk) {
3505
+ this.sdk = sdk;
3506
+ }
3507
+ sdk;
3508
+ async capabilities() {
3509
+ return createVprogsCapabilities();
3510
+ }
3511
+ async status() {
3512
+ return createVprogsStatus();
3513
+ }
3514
+ async inspect(targetPath) {
3515
+ return inspectVprogsArtifact(targetPath, this.sdk.cwd);
3516
+ }
3517
+ };
3518
+ function createVprogsCapabilities() {
3519
+ return {
3520
+ ok: true,
3521
+ schema: HardkasSchemas8.VProgsCapabilitiesV1,
3522
+ status: "VPROGS_INSPECT_SURFACE_READY",
3523
+ claims: vprogsClaims(),
3524
+ errors: [
3525
+ "VPROGS_RUNTIME_NOT_CLAIMED",
3526
+ "VPROGS_STABLE_API_NOT_CLAIMED",
3527
+ "ZK_ONCHAIN_VERIFICATION_NOT_CLAIMED"
3528
+ ]
3529
+ };
3530
+ }
3531
+ function createVprogsStatus() {
3532
+ return {
3533
+ ok: true,
3534
+ schema: HardkasSchemas8.VProgsStatusV1,
3535
+ status: "VPROGS_INSPECT_SURFACE_READY",
3536
+ claims: vprogsClaims()
3537
+ };
3538
+ }
3539
+ async function inspectVprogsArtifact(targetPath, workspaceRoot = process.cwd()) {
3540
+ const resolved = path7.resolve(workspaceRoot, targetPath);
3541
+ if (!fs7.existsSync(resolved)) {
3542
+ return {
3543
+ ok: false,
3544
+ schema: HardkasSchemas8.VProgsInspectV1,
3545
+ status: "VPROGS_ARTIFACT_INVALID",
3546
+ path: path7.relative(workspaceRoot, resolved).replace(/\\/g, "/"),
3547
+ claims: vprogsClaims(),
3548
+ issues: [
3549
+ {
3550
+ code: "VPROGS_ARTIFACT_MISSING",
3551
+ message: `Missing ${resolved}.`,
3552
+ file: resolved
3553
+ }
3554
+ ]
3555
+ };
3556
+ }
3557
+ try {
3558
+ const artifact = JSON.parse(fs7.readFileSync(resolved, "utf8"));
3559
+ return {
3560
+ ok: true,
3561
+ schema: HardkasSchemas8.VProgsInspectV1,
3562
+ status: "VPROGS_ARTIFACT_INSPECTED",
3563
+ path: path7.relative(workspaceRoot, resolved).replace(/\\/g, "/"),
3564
+ artifactHash: calculateContentHash5(artifact),
3565
+ artifactSchema: artifact.schema,
3566
+ claims: vprogsClaims(),
3567
+ issues: []
3568
+ };
3569
+ } catch (error) {
3570
+ return {
3571
+ ok: false,
3572
+ schema: HardkasSchemas8.VProgsInspectV1,
3573
+ status: "VPROGS_ARTIFACT_INVALID",
3574
+ path: path7.relative(workspaceRoot, resolved).replace(/\\/g, "/"),
3575
+ claims: vprogsClaims(),
3576
+ issues: [
3577
+ {
3578
+ code: "VPROGS_ARTIFACT_INVALID",
3579
+ message: error?.message || "Invalid vProgs artifact JSON.",
3580
+ file: resolved
3581
+ }
3582
+ ]
3583
+ };
3584
+ }
3585
+ }
3586
+ function vprogsClaims() {
3587
+ return {
3588
+ vProgsArtifactInspection: "READY",
3589
+ vProgsRuntime: "NOT_CLAIMED",
3590
+ vProgsStableApi: "NOT_CLAIMED",
3591
+ zkOnchainVerification: "NOT_CLAIMED",
3592
+ vmConsensusEquivalence: "NOT_CLAIMED",
3593
+ mainnet: "BLOCKED_BY_POLICY"
3594
+ };
3595
+ }
3596
+
3597
+ // src/programmability.ts
3598
+ import fs8 from "fs";
3599
+ import path8 from "path";
3600
+ import { calculateContentHash as calculateContentHash6, verifyArtifactIntegritySync } from "@hardkas/artifacts";
3601
+ import { HardkasSchemas as HardkasSchemas9 } from "@hardkas/artifacts";
3602
+ var HardkasProgrammability = class {
3603
+ constructor(sdk) {
3604
+ this.sdk = sdk;
3605
+ this.corpus = {
3606
+ verify: (options = {}) => this.verifyCorpus(options)
3607
+ };
3608
+ this.app = {
3609
+ plan: (options = {}) => this.planApp(options)
3610
+ };
3611
+ }
3612
+ sdk;
3613
+ corpus;
3614
+ app;
3615
+ async capabilities() {
3616
+ return createProgrammabilityCapabilities();
3617
+ }
3618
+ async inspect(options) {
3619
+ if (options.kind === "zk") {
3620
+ const result = await this.sdk.zk.proof.inspect(options.path);
3621
+ return {
3622
+ ok: result.ok,
3623
+ schema: HardkasSchemas9.ProgrammabilityInspectV1,
3624
+ status: result.ok ? "PROGRAMMABILITY_ARTIFACT_INSPECTED" : "PROGRAMMABILITY_ARTIFACT_INVALID",
3625
+ kind: "zk",
3626
+ path: result.path,
3627
+ sourceStatus: result.status,
3628
+ claims: programmabilityClaims(),
3629
+ issues: result.issues
3630
+ };
3631
+ }
3632
+ if (options.kind === "vprog") {
3633
+ const result = await this.sdk.vprogs.inspect(options.path);
3634
+ return {
3635
+ ok: result.ok,
3636
+ schema: HardkasSchemas9.ProgrammabilityInspectV1,
3637
+ status: result.ok ? "PROGRAMMABILITY_ARTIFACT_INSPECTED" : "PROGRAMMABILITY_ARTIFACT_INVALID",
3638
+ kind: "vprog",
3639
+ path: result.path,
3640
+ ...result.artifactSchema ? { artifactSchema: result.artifactSchema } : {},
3641
+ ...result.artifactHash ? { contentHash: result.artifactHash } : {},
3642
+ sourceStatus: result.status,
3643
+ claims: programmabilityClaims(),
3644
+ issues: result.issues
3645
+ };
3646
+ }
3647
+ return inspectJsonArtifact(this.sdk.cwd, options.path, "silver");
3648
+ }
3649
+ async verify(options) {
3650
+ if (options.kind === "zk") {
3651
+ const result2 = await this.sdk.zk.proof.verifyLocal(options.path);
3652
+ return {
3653
+ ok: result2.ok,
3654
+ schema: HardkasSchemas9.ProgrammabilityVerifyV1,
3655
+ status: result2.ok ? "PROGRAMMABILITY_VERIFY_PASS" : "PROGRAMMABILITY_VERIFY_PARTIAL",
3656
+ kind: "zk",
3657
+ path: result2.path,
3658
+ sourceStatus: result2.status,
3659
+ claims: programmabilityClaims(),
3660
+ issues: result2.issues
3661
+ };
3662
+ }
3663
+ if (options.kind === "vprog") {
3664
+ const inspected = await this.sdk.vprogs.inspect(options.path);
3665
+ return {
3666
+ ok: inspected.ok,
3667
+ schema: HardkasSchemas9.ProgrammabilityVerifyV1,
3668
+ status: inspected.ok ? "PROGRAMMABILITY_VERIFY_PASS" : "PROGRAMMABILITY_VERIFY_FAIL",
3669
+ kind: "vprog",
3670
+ path: inspected.path,
3671
+ sourceStatus: inspected.status,
3672
+ claims: programmabilityClaims(),
3673
+ issues: inspected.issues
3674
+ };
3675
+ }
3676
+ const resolved = path8.resolve(this.sdk.cwd, options.path);
3677
+ const result = verifyArtifactIntegritySync(resolved, { strict: false });
3678
+ return {
3679
+ ok: result.ok,
3680
+ schema: HardkasSchemas9.ProgrammabilityVerifyV1,
3681
+ status: result.ok ? "PROGRAMMABILITY_VERIFY_PASS" : "PROGRAMMABILITY_VERIFY_FAIL",
3682
+ kind: "silver",
3683
+ path: path8.relative(this.sdk.cwd, resolved).replace(/\\/g, "/"),
3684
+ sourceStatus: result.ok ? "ARTIFACT_INTEGRITY_PASS" : "ARTIFACT_INTEGRITY_FAIL",
3685
+ claims: programmabilityClaims(),
3686
+ issues: result.issues.map((issue) => ({
3687
+ code: String(issue.code),
3688
+ message: issue.message,
3689
+ ...issue.path ? { file: issue.path } : {}
3690
+ }))
3691
+ };
3692
+ }
3693
+ async verifyCorpus(options) {
3694
+ const root = path8.resolve(this.sdk.cwd, options.path ?? "fixtures/toccata-v2");
3695
+ const include = new Set(options.include ?? ["silver", "zk", "vprogs"]);
3696
+ const issues = [];
3697
+ const manifestPath = path8.join(root, "manifest.json");
3698
+ const manifest = readJson2(manifestPath, issues);
3699
+ if (manifest) {
3700
+ expectEqual3(
3701
+ manifest.schema,
3702
+ HardkasSchemas9.ToccataProgrammabilityCorpusV1,
3703
+ issues,
3704
+ "PROGRAMMABILITY_CORPUS_SCHEMA_INVALID",
3705
+ manifestPath
3706
+ );
3707
+ expectEqual3(
3708
+ manifest.network,
3709
+ "simnet",
3710
+ issues,
3711
+ "PROGRAMMABILITY_CORPUS_NETWORK_INVALID",
3712
+ manifestPath
3713
+ );
3714
+ expectEqual3(
3715
+ manifest.profile,
3716
+ "toccata-v2",
3717
+ issues,
3718
+ "PROGRAMMABILITY_CORPUS_PROFILE_INVALID",
3719
+ manifestPath
3720
+ );
3721
+ expectEqual3(
3722
+ manifest.claims?.artifactCoherence,
3723
+ "READY_MATCH",
3724
+ issues,
3725
+ "PROGRAMMABILITY_CLAIM_INVALID",
3726
+ manifestPath
3727
+ );
3728
+ expectEqual3(
3729
+ manifest.claims?.runtimeOutcome,
3730
+ "PARTIAL",
3731
+ issues,
3732
+ "PROGRAMMABILITY_CLAIM_INVALID",
3733
+ manifestPath
3734
+ );
3735
+ expectEqual3(
3736
+ manifest.claims?.vmConsensusEquivalence,
3737
+ "NOT_CLAIMED",
3738
+ issues,
3739
+ "PROGRAMMABILITY_CLAIM_INVALID",
3740
+ manifestPath
3741
+ );
3742
+ expectEqual3(
3743
+ manifest.claims?.mainnet,
3744
+ "BLOCKED_BY_POLICY",
3745
+ issues,
3746
+ "PROGRAMMABILITY_CLAIM_INVALID",
3747
+ manifestPath
3748
+ );
3749
+ if (!Array.isArray(manifest.expectedKnownLimitations) || !manifest.expectedKnownLimitations.includes("PARTIAL_VM_SIMULATION")) {
3750
+ issues.push({
3751
+ code: "PROGRAMMABILITY_LIMITATION_NOT_DECLARED",
3752
+ message: "Root corpus must declare PARTIAL_VM_SIMULATION.",
3753
+ file: manifestPath
3754
+ });
3755
+ }
3756
+ }
3757
+ let silver = "SKIPPED";
3758
+ let zk = "SKIPPED";
3759
+ let vprogs = "SKIPPED";
3760
+ if (include.has("silver")) {
3761
+ const result = await this.sdk.corpus.verify(
3762
+ path8.join(path8.relative(this.sdk.cwd, root), "silver")
3763
+ );
3764
+ silver = result.ok ? "PASS" : "FAIL";
3765
+ issues.push(...result.issues);
3766
+ }
3767
+ if (include.has("zk")) {
3768
+ const result = await this.sdk.zk.corpus.verify(
3769
+ path8.join(path8.relative(this.sdk.cwd, root), "zk")
3770
+ );
3771
+ zk = result.ok ? "PASS" : "FAIL";
3772
+ issues.push(...result.issues);
3773
+ }
3774
+ if (include.has("vprogs")) {
3775
+ const artifact = manifest?.components?.vprogs?.artifact ?? "vprogs/inspect-only-artifact.json";
3776
+ const result = await this.sdk.vprogs.inspect(
3777
+ path8.join(path8.relative(this.sdk.cwd, root), artifact)
3778
+ );
3779
+ vprogs = result.ok ? "PASS" : "FAIL";
3780
+ issues.push(...result.issues);
3781
+ }
3782
+ const ok = issues.length === 0;
3783
+ return {
3784
+ ok,
3785
+ schema: HardkasSchemas9.ProgrammabilityCorpusReportV1,
3786
+ path: path8.relative(this.sdk.cwd, root).replace(/\\/g, "/"),
3787
+ status: ok ? "PROGRAMMABILITY_CORPUS_PASS" : "PROGRAMMABILITY_CORPUS_FAIL",
3788
+ summary: {
3789
+ silver,
3790
+ zk,
3791
+ vprogs,
3792
+ rootManifest: manifest ? "PASS" : "FAIL",
3793
+ knownLimitations: Array.isArray(manifest?.expectedKnownLimitations) ? manifest.expectedKnownLimitations : []
3794
+ },
3795
+ claims: programmabilityClaims(),
3796
+ issues
3797
+ };
3798
+ }
3799
+ planApp(options) {
3800
+ const kind = options.kind ?? "full-lab";
3801
+ const template = options.template ?? defaultTemplate(kind);
3802
+ return {
3803
+ ok: true,
3804
+ schema: HardkasSchemas9.ProgrammabilityAppPlanV1,
3805
+ status: "PROGRAMMABILITY_APP_PLAN_READY",
3806
+ kind,
3807
+ template,
3808
+ commands: commandsForKind(kind),
3809
+ sdkSurfaces: sdkSurfacesForKind(kind),
3810
+ claims: programmabilityClaims(),
3811
+ nonClaims: nonClaims()
3812
+ };
3813
+ }
3814
+ };
3815
+ function createProgrammabilityCapabilities() {
3816
+ return {
3817
+ ok: true,
3818
+ schema: HardkasSchemas9.ProgrammabilityCapabilitiesV1,
3819
+ status: "PROGRAMMABILITY_SURFACE_READY",
3820
+ surfaces: {
3821
+ silverScript: "SILVERSCRIPT_BUILDER_READY",
3822
+ zkCorpus: "ZK_CORPUS_SURFACE_READY",
3823
+ groth16FixtureCoherence: "READY_GROTH16_FIXTURE_COHERENCE",
3824
+ risc0Inspect: "RISC0_INSPECT_SURFACE_READY",
3825
+ vProgsInspect: "VPROGS_INSPECT_SURFACE_READY"
3826
+ },
3827
+ claims: programmabilityClaims(),
3828
+ nonClaims: nonClaims()
3829
+ };
3830
+ }
3831
+ function programmabilityClaims() {
3832
+ return {
3833
+ artifactCoherence: "READY_MATCH",
3834
+ silverScriptBuilder: "SILVERSCRIPT_BUILDER_READY",
3835
+ zkCorpusSurface: "ZK_CORPUS_SURFACE_READY",
3836
+ zkLocalVerification: "READY_GROTH16_FIXTURE_COHERENCE",
3837
+ risc0InspectSurface: "RISC0_INSPECT_SURFACE_READY",
3838
+ vProgsInspectSurface: "VPROGS_INSPECT_SURFACE_READY",
3839
+ runtimeOutcome: "PARTIAL",
3840
+ vmConsensusEquivalence: "NOT_CLAIMED",
3841
+ zkOnchainVerification: "NOT_CLAIMED",
3842
+ vProgsRuntime: "NOT_CLAIMED",
3843
+ vProgsStableApi: "NOT_CLAIMED",
3844
+ mainnet: "BLOCKED_BY_POLICY"
3845
+ };
3846
+ }
3847
+ function inspectJsonArtifact(workspaceRoot, targetPath, kind) {
3848
+ const resolved = path8.resolve(workspaceRoot, targetPath);
3849
+ const issues = [];
3850
+ const artifact = readJson2(resolved, issues);
3851
+ const ok = Boolean(artifact);
3852
+ return {
3853
+ ok,
3854
+ schema: HardkasSchemas9.ProgrammabilityInspectV1,
3855
+ status: ok ? "PROGRAMMABILITY_ARTIFACT_INSPECTED" : "PROGRAMMABILITY_ARTIFACT_INVALID",
3856
+ kind,
3857
+ path: path8.relative(workspaceRoot, resolved).replace(/\\/g, "/"),
3858
+ ...artifact?.schema ? { artifactSchema: artifact.schema } : {},
3859
+ ...artifact ? { contentHash: calculateContentHash6(artifact, artifact.hashVersion ?? 4) } : {},
3860
+ claims: programmabilityClaims(),
3861
+ issues
3862
+ };
3863
+ }
3864
+ function readJson2(filePath, issues) {
3865
+ if (!fs8.existsSync(filePath)) {
3866
+ issues.push({
3867
+ code: "PROGRAMMABILITY_FILE_MISSING",
3868
+ message: `Missing ${filePath}.`,
3869
+ file: filePath
3870
+ });
3871
+ return void 0;
3872
+ }
3873
+ try {
3874
+ return JSON.parse(fs8.readFileSync(filePath, "utf8"));
3875
+ } catch (error) {
3876
+ issues.push({
3877
+ code: "PROGRAMMABILITY_JSON_INVALID",
3878
+ message: error?.message || `Invalid JSON in ${filePath}.`,
3879
+ file: filePath
3880
+ });
3881
+ return void 0;
3882
+ }
3883
+ }
3884
+ function expectEqual3(actual, expected, issues, code, file) {
3885
+ if (actual !== expected) {
3886
+ issues.push({
3887
+ code,
3888
+ message: `Expected ${String(expected)}, got ${String(actual)}.`,
3889
+ file
3890
+ });
3891
+ }
3892
+ }
3893
+ function defaultTemplate(kind) {
3894
+ if (kind === "silver") return "templates/programmability/silver-policy-app";
3895
+ if (kind === "zk") return "templates/programmability/zk-fixture-app";
3896
+ if (kind === "vprog") return "templates/programmability/vprogs-inspect-app";
3897
+ return "templates/programmability/full-lab-app";
3898
+ }
3899
+ function commandsForKind(kind) {
3900
+ const common = [
3901
+ "hardkas programmability capabilities --json",
3902
+ "hardkas programmability corpus verify fixtures/toccata-v2 --json"
3903
+ ];
3904
+ if (kind === "silver") return [...common, "hardkas silver inspect <artifact>"];
3905
+ if (kind === "zk")
3906
+ return [...common, "hardkas zk corpus verify fixtures/toccata-v2/zk --json"];
3907
+ if (kind === "vprog") return [...common, "hardkas vprogs inspect <artifact> --json"];
3908
+ return [
3909
+ ...common,
3910
+ "hardkas silver inspect <artifact>",
3911
+ "hardkas zk corpus verify fixtures/toccata-v2/zk --json",
3912
+ "hardkas vprogs inspect <artifact> --json"
3913
+ ];
3914
+ }
3915
+ function sdkSurfacesForKind(kind) {
3916
+ const common = [
3917
+ "hardkas.programmability.capabilities()",
3918
+ "hardkas.programmability.corpus.verify()"
3919
+ ];
3920
+ if (kind === "silver") return [...common, "hardkas.silver.*"];
3921
+ if (kind === "zk")
3922
+ return [...common, "hardkas.zk.proof.*", "hardkas.zk.corpus.verify()"];
3923
+ if (kind === "vprog") return [...common, "hardkas.vprogs.inspect()"];
3924
+ return [...common, "hardkas.silver.*", "hardkas.zk.*", "hardkas.vprogs.*"];
3925
+ }
3926
+ function nonClaims() {
3927
+ return [
3928
+ "no mainnet",
3929
+ "no testnet claim",
3930
+ "no bridge",
3931
+ "no trustless exit",
3932
+ "no on-chain ZK verification",
3933
+ "no full vProgs runtime",
3934
+ "no VM/consensus equivalence"
3935
+ ];
3936
+ }
3937
+
1980
3938
  // src/index.ts
1981
3939
  import { defineHardkasConfig as defineHardkasConfig2 } from "@hardkas/config";
1982
3940
 
@@ -2012,16 +3970,16 @@ var defineTask = taskRegistry.defineTask.bind(taskRegistry);
2012
3970
  import { buildPaymentPlan as buildPaymentPlan2 } from "@hardkas/tx-builder";
2013
3971
  import { signTxPlanArtifact as signTxPlanArtifact2 } from "@hardkas/accounts";
2014
3972
  import {
2015
- writeArtifact as writeArtifact3,
3973
+ writeArtifact as writeArtifact4,
2016
3974
  createTxPlanArtifact as createTxPlanArtifact2,
2017
3975
  ARTIFACT_SCHEMAS as ARTIFACT_SCHEMAS2,
2018
- HARDKAS_VERSION as HARDKAS_VERSION3
3976
+ HARDKAS_VERSION as HARDKAS_VERSION5
2019
3977
  } from "@hardkas/artifacts";
2020
3978
  import {
2021
3979
  SOMPI_PER_KAS,
2022
3980
  HardkasError as HardkasError4,
2023
- parseKasToSompi as parseKasToSompi2,
2024
- formatSompi as formatSompi2
3981
+ parseKasToSompi as parseKasToSompi3,
3982
+ formatSompiToKas as formatSompiToKas2
2025
3983
  } from "@hardkas/core";
2026
3984
  var Hardkas = class _Hardkas {
2027
3985
  constructor(config, options, rpc) {
@@ -2047,6 +4005,12 @@ var Hardkas = class _Hardkas {
2047
4005
  this.replay = new HardkasReplay(this);
2048
4006
  this.lineage = new HardkasLineage(this);
2049
4007
  this.workflow = new HardkasWorkflow(this);
4008
+ this.capabilitiesApi = new HardkasCapabilitiesApi();
4009
+ this.corpus = new HardkasCorpus(this);
4010
+ this.silver = new HardkasSilver(this);
4011
+ this.zk = new HardkasZk(this);
4012
+ this.vprogs = new HardkasVprogs(this);
4013
+ this.programmability = new HardkasProgrammability(this);
2050
4014
  }
2051
4015
  config;
2052
4016
  workspace;
@@ -2059,6 +4023,12 @@ var Hardkas = class _Hardkas {
2059
4023
  replay;
2060
4024
  lineage;
2061
4025
  workflow;
4026
+ capabilitiesApi;
4027
+ corpus;
4028
+ silver;
4029
+ zk;
4030
+ vprogs;
4031
+ programmability;
2062
4032
  signer;
2063
4033
  mode;
2064
4034
  policy;
@@ -2080,21 +4050,23 @@ var Hardkas = class _Hardkas {
2080
4050
  const activeNetwork = options.network || loaded.config.defaultNetwork || "simnet";
2081
4051
  const isSimulated = activeNetwork === "simulated" || loaded.config.networks?.[activeNetwork]?.kind === "simulated";
2082
4052
  const autoBootstrap = options.autoBootstrap ?? (isSimulated ? true : false);
2083
- const fs4 = await import("fs");
2084
- const path4 = await import("path");
4053
+ const fs9 = await import("fs");
4054
+ const path9 = await import("path");
2085
4055
  const cwd = options.cwd || process.cwd();
2086
- const hardkasDir = path4.join(cwd, ".hardkas");
4056
+ const hardkasDir = path9.join(cwd, ".hardkas");
2087
4057
  if (autoBootstrap) {
2088
4058
  if (!isSimulated) {
2089
4059
  if (options.logger) {
2090
- options.logger.warn("[HardKAS] autoBootstrap ignored for non-simulated network");
4060
+ options.logger.warn(
4061
+ "[HardKAS] autoBootstrap ignored for non-simulated network"
4062
+ );
2091
4063
  }
2092
4064
  } else {
2093
- if (!fs4.existsSync(hardkasDir)) {
4065
+ if (!fs9.existsSync(hardkasDir)) {
2094
4066
  if (options.logger) {
2095
4067
  options.logger.info("[HardKAS] Auto-bootstrapping simulated workspace");
2096
4068
  }
2097
- fs4.mkdirSync(hardkasDir, { recursive: true });
4069
+ fs9.mkdirSync(hardkasDir, { recursive: true });
2098
4070
  }
2099
4071
  try {
2100
4072
  const { loadOrCreateLocalnetState } = await import("@hardkas/localnet");
@@ -2103,8 +4075,11 @@ var Hardkas = class _Hardkas {
2103
4075
  }
2104
4076
  }
2105
4077
  } else {
2106
- if (!fs4.existsSync(hardkasDir)) {
2107
- throw new HardkasError3("NOT_INITIALIZED", "Workspace not initialized. Run npx hardkas init . or pass autoBootstrap: true.");
4078
+ if (!fs9.existsSync(hardkasDir)) {
4079
+ throw new HardkasError3(
4080
+ "NOT_INITIALIZED",
4081
+ "Workspace not initialized. Run npx hardkas init . or pass autoBootstrap: true."
4082
+ );
2108
4083
  }
2109
4084
  }
2110
4085
  if (options.network) {
@@ -2135,6 +4110,9 @@ var Hardkas = class _Hardkas {
2135
4110
  get cwd() {
2136
4111
  return this.config.cwd;
2137
4112
  }
4113
+ async capabilities() {
4114
+ return this.capabilitiesApi.get();
4115
+ }
2138
4116
  /**
2139
4117
  * Validates an action against the active security policy.
2140
4118
  * Throws HardkasError if the policy is violated.
@@ -2164,26 +4142,43 @@ var Hardkas = class _Hardkas {
2164
4142
  };
2165
4143
  export {
2166
4144
  ARTIFACT_SCHEMAS2 as ARTIFACT_SCHEMAS,
2167
- HARDKAS_VERSION3 as HARDKAS_VERSION,
4145
+ HARDKAS_VERSION5 as HARDKAS_VERSION,
2168
4146
  Hardkas,
2169
4147
  HardkasAccounts,
2170
4148
  HardkasArtifactsManager,
4149
+ HardkasCapabilitiesApi,
4150
+ HardkasCorpus,
2171
4151
  HardkasError4 as HardkasError,
2172
4152
  HardkasL2,
2173
4153
  HardkasLineage,
2174
4154
  HardkasLocalnet,
4155
+ HardkasProgrammability,
2175
4156
  HardkasQuery,
2176
4157
  HardkasReplay,
4158
+ HardkasSilver,
2177
4159
  HardkasTx,
4160
+ HardkasVprogs,
2178
4161
  HardkasWorkspace,
4162
+ HardkasZk,
2179
4163
  SOMPI_PER_KAS,
2180
4164
  buildPaymentPlan2 as buildPaymentPlan,
4165
+ createHardkasCapabilities,
2181
4166
  createHardkasClient,
4167
+ createProgrammabilityCapabilities,
2182
4168
  createTxPlanArtifact2 as createTxPlanArtifact,
4169
+ createVprogsCapabilities,
4170
+ createVprogsStatus,
4171
+ createZkCapabilities,
2183
4172
  defineHardkasConfig2 as defineHardkasConfig,
2184
4173
  defineTask,
2185
- formatSompi2 as formatSompi,
2186
- parseKasToSompi2 as parseKasToSompi,
4174
+ formatSompiToKas2 as formatSompiToKas,
4175
+ inspectVprogsArtifact,
4176
+ inspectZkProof,
4177
+ parseKasToSompi3 as parseKasToSompi,
4178
+ programmabilityClaims,
2187
4179
  signTxPlanArtifact2 as signTxPlanArtifact,
2188
- writeArtifact3 as writeArtifact
4180
+ verifyToccataCorpus,
4181
+ verifyZkCorpus,
4182
+ verifyZkProofLocal,
4183
+ writeArtifact4 as writeArtifact
2189
4184
  };