@hardkas/sdk 0.9.0-alpha → 0.9.2-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.
- package/README.md +51 -51
- package/dist/{chunk-V32UCCTZ.js → chunk-IR6EJBJT.js} +1 -1
- package/dist/client.js +1 -1
- package/dist/index.d.ts +492 -7
- package/dist/index.js +2111 -116
- package/package.json +13 -13
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createHardkasClient
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-IR6EJBJT.js";
|
|
4
4
|
|
|
5
5
|
// src/index.ts
|
|
6
6
|
import {
|
|
@@ -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 {
|
|
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:
|
|
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
|
|
50
|
+
* Lists all available HardKAS accounts.
|
|
51
51
|
*/
|
|
52
52
|
async list() {
|
|
53
|
-
|
|
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
|
|
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(
|
|
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 {
|
|
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(
|
|
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: [
|
|
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(
|
|
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(
|
|
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({
|
|
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:
|
|
282
|
-
const newHash =
|
|
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 =
|
|
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, {
|
|
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(
|
|
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:
|
|
358
|
-
const newHash =
|
|
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 =
|
|
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, {
|
|
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 ===
|
|
380
|
-
const signedArtifact2 = await this.sdk.signer.signTransaction(
|
|
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 ===
|
|
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,
|
|
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:
|
|
489
|
-
const hash = calculateContentHash(draft,
|
|
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 ===
|
|
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:
|
|
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:
|
|
535
|
-
schemaVersion:
|
|
536
|
-
hardkasVersion:
|
|
565
|
+
schema: HardkasSchemas.SignedTx,
|
|
566
|
+
schemaVersion: HardkasSchemas.ArtifactV1,
|
|
567
|
+
hardkasVersion: HARDKAS_VERSION6,
|
|
537
568
|
version: ARTIFACT_VERSION2,
|
|
538
|
-
hashVersion:
|
|
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,
|
|
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,
|
|
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,
|
|
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(
|
|
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,9 +646,13 @@ 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, {
|
|
649
|
+
await this.sdk.artifacts.verify(target, {
|
|
650
|
+
throwOnInvalid: true,
|
|
651
|
+
strict: true,
|
|
652
|
+
enforceMetadata: false
|
|
653
|
+
});
|
|
617
654
|
} catch (e) {
|
|
618
|
-
if (e.message.includes("PARENT_MISSING")) {
|
|
655
|
+
if ((e instanceof Error ? e instanceof Error ? e instanceof Error ? e.message : String(e) : String(e) : String(e)).includes("PARENT_MISSING")) {
|
|
619
656
|
throw new Error("parent_plan_unresolved: Missing context plan for simulation.");
|
|
620
657
|
}
|
|
621
658
|
throw e;
|
|
@@ -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, {
|
|
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
|
|
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, {
|
|
698
|
+
targetObj = await this.sdk.artifacts.read(target, {
|
|
699
|
+
expectedSchema: ARTIFACT_SCHEMAS.TX_PLAN
|
|
700
|
+
});
|
|
660
701
|
} catch (e) {
|
|
661
|
-
throw new Error(
|
|
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, {
|
|
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:
|
|
762
|
+
schemaVersion: HardkasSchemas.TxReceiptV1,
|
|
718
763
|
hardkasVersion: HARDKAS_VERSION,
|
|
719
764
|
version: ARTIFACT_VERSION,
|
|
720
765
|
hashVersion: CURRENT_HASH_VERSION,
|
|
@@ -816,9 +861,13 @@ 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, {
|
|
864
|
+
await this.sdk.artifacts.verify(signedArtifact, {
|
|
865
|
+
throwOnInvalid: true,
|
|
866
|
+
strict: true,
|
|
867
|
+
enforceMetadata: false
|
|
868
|
+
});
|
|
820
869
|
} catch (e) {
|
|
821
|
-
if (e.message.includes("PARENT_MISSING")) {
|
|
870
|
+
if ((e instanceof Error ? e instanceof Error ? e instanceof Error ? e.message : String(e) : String(e) : String(e)).includes("PARENT_MISSING")) {
|
|
822
871
|
throw new Error("parent_plan_unresolved: Missing context plan for simulation.");
|
|
823
872
|
}
|
|
824
873
|
throw e;
|
|
@@ -840,11 +889,13 @@ var HardkasTx = class {
|
|
|
840
889
|
try {
|
|
841
890
|
simResult = await this.simulate(signedArtifact, simOpts);
|
|
842
891
|
} catch (e) {
|
|
843
|
-
if (e.message && e.message.includes("invalid simulated input")) {
|
|
892
|
+
if ((e instanceof Error ? e instanceof Error ? e instanceof Error ? e.message : String(e) : String(e) : String(e)) && (e instanceof Error ? e instanceof Error ? e instanceof Error ? e.message : String(e) : String(e) : String(e)).includes("invalid simulated input")) {
|
|
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, {
|
|
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(
|
|
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,
|
|
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(
|
|
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
|
|
993
|
-
const
|
|
994
|
-
const hardkasDir =
|
|
995
|
-
if (!
|
|
996
|
-
throw new Error(
|
|
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(
|
|
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 =
|
|
1068
|
+
const dbPath = path9.join(hardkasDir, "store.db");
|
|
1008
1069
|
const store = new HardkasStore({ dbPath });
|
|
1009
1070
|
let stats;
|
|
1010
1071
|
try {
|
|
@@ -1026,8 +1087,10 @@ var HardkasQuery = class {
|
|
|
1026
1087
|
}
|
|
1027
1088
|
);
|
|
1028
1089
|
} catch (e) {
|
|
1029
|
-
if (e.message?.includes("SQLITE") || e.message?.includes("Cannot read properties")) {
|
|
1030
|
-
throw new Error(
|
|
1090
|
+
if ((e instanceof Error ? e instanceof Error ? e instanceof Error ? e.message : String(e) : String(e) : String(e))?.includes("SQLITE") || (e instanceof Error ? e instanceof Error ? e instanceof Error ? e.message : String(e) : String(e) : String(e))?.includes("Cannot read properties")) {
|
|
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
|
-
*
|
|
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.2-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.2-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.2-alpha because it
|
|
1187
|
+
* depends on a local stratum/miner companion and host Docker state.
|
|
1077
1188
|
*/
|
|
1078
|
-
async
|
|
1079
|
-
|
|
1080
|
-
|
|
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.2-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
|
-
|
|
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 ===
|
|
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 ===
|
|
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 ===
|
|
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, {
|
|
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
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
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 !==
|
|
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 || [];
|
|
@@ -1355,7 +1548,7 @@ var HardkasReplay = class {
|
|
|
1355
1548
|
}
|
|
1356
1549
|
report = { invariantsOk: determinismOk && contaminationOk };
|
|
1357
1550
|
} catch (e) {
|
|
1358
|
-
verifyErrorMsg = `Workflow Replay failed: ${e.message}`;
|
|
1551
|
+
verifyErrorMsg = `Workflow Replay failed: ${e instanceof Error ? e instanceof Error ? e instanceof Error ? e.message : String(e) : String(e) : String(e)}`;
|
|
1359
1552
|
lineageOk = false;
|
|
1360
1553
|
determinismOk = false;
|
|
1361
1554
|
}
|
|
@@ -1371,7 +1564,7 @@ var HardkasReplay = class {
|
|
|
1371
1564
|
plan = await readTxPlanArtifact(planPath);
|
|
1372
1565
|
receipt = await readTxReceiptArtifact2(receiptPath);
|
|
1373
1566
|
} catch (err) {
|
|
1374
|
-
verifyErrorMsg = err.message;
|
|
1567
|
+
verifyErrorMsg = err instanceof Error ? err instanceof Error ? err instanceof Error ? err.message : String(err) : String(err) : String(err);
|
|
1375
1568
|
}
|
|
1376
1569
|
if (!verifyErrorMsg && plan && receipt) {
|
|
1377
1570
|
try {
|
|
@@ -1388,7 +1581,7 @@ var HardkasReplay = class {
|
|
|
1388
1581
|
const reportPath = path.join(this.sdk.workspace.artifactsDir, reportFilename);
|
|
1389
1582
|
await writeArtifact2(reportPath, report);
|
|
1390
1583
|
} catch (err) {
|
|
1391
|
-
verifyErrorMsg = `Replay execution failed: ${err.message}`;
|
|
1584
|
+
verifyErrorMsg = `Replay execution failed: ${err instanceof Error ? err instanceof Error ? err instanceof Error ? err.message : String(err) : String(err) : String(err)}`;
|
|
1392
1585
|
}
|
|
1393
1586
|
}
|
|
1394
1587
|
} else {
|
|
@@ -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:
|
|
1508
|
-
record.hashVersion =
|
|
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:
|
|
1530
|
-
await
|
|
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(
|
|
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(
|
|
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(
|
|
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)
|
|
1666
|
-
|
|
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 {
|
|
1877
|
+
return {
|
|
1878
|
+
valid: false,
|
|
1879
|
+
reason: "missing_artifact",
|
|
1880
|
+
message: e instanceof Error ? e instanceof Error ? e instanceof Error ? e.message : String(e) : String(e) : String(e),
|
|
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(
|
|
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(
|
|
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:
|
|
1962
|
+
const { calculateContentHash: calculateContentHash7 } = await import("@hardkas/artifacts");
|
|
1748
1963
|
const intentPayload = {
|
|
1749
|
-
type:
|
|
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:
|
|
1981
|
+
workspaceSchemaVersion: HardkasSchemas4.WorkflowV1
|
|
1767
1982
|
};
|
|
1768
|
-
const intentHash =
|
|
1983
|
+
const intentHash = calculateContentHash7(intentPayload);
|
|
1769
1984
|
const workflowId = `wf_${intentHash.slice(0, 16)}`;
|
|
1770
1985
|
const artifactSteps = [];
|
|
1771
1986
|
const producedArtifacts = [];
|
|
@@ -1916,11 +2131,10 @@ 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",
|
|
1923
|
-
message: e.message,
|
|
2137
|
+
message: e instanceof Error ? e instanceof Error ? e instanceof Error ? e.message : String(e) : String(e) : String(e),
|
|
1924
2138
|
redacted: false
|
|
1925
2139
|
};
|
|
1926
2140
|
artifactSteps.push({
|
|
@@ -1929,14 +2143,14 @@ var HardkasWorkflow = class {
|
|
|
1929
2143
|
startedAt,
|
|
1930
2144
|
completedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1931
2145
|
// hardkas-determinism-allow: step failed timestamp
|
|
1932
|
-
error: e.message
|
|
2146
|
+
error: e instanceof Error ? e instanceof Error ? e instanceof Error ? e.message : String(e) : String(e) : String(e)
|
|
1933
2147
|
});
|
|
1934
2148
|
break;
|
|
1935
2149
|
}
|
|
1936
2150
|
}
|
|
1937
2151
|
const executionMode = this.sdk.network === "simulated" ? "simulated" : "real";
|
|
1938
2152
|
const artifact = {
|
|
1939
|
-
schema:
|
|
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 =
|
|
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.2-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.2-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.2-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
|
|
3973
|
+
writeArtifact as writeArtifact4,
|
|
2016
3974
|
createTxPlanArtifact as createTxPlanArtifact2,
|
|
2017
3975
|
ARTIFACT_SCHEMAS as ARTIFACT_SCHEMAS2,
|
|
2018
|
-
HARDKAS_VERSION as
|
|
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
|
|
2024
|
-
|
|
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
|
|
2084
|
-
const
|
|
4053
|
+
const fs9 = await import("fs");
|
|
4054
|
+
const path9 = await import("path");
|
|
2085
4055
|
const cwd = options.cwd || process.cwd();
|
|
2086
|
-
const hardkasDir =
|
|
4056
|
+
const hardkasDir = path9.join(cwd, ".hardkas");
|
|
2087
4057
|
if (autoBootstrap) {
|
|
2088
4058
|
if (!isSimulated) {
|
|
2089
4059
|
if (options.logger) {
|
|
2090
|
-
options.logger.warn(
|
|
4060
|
+
options.logger.warn(
|
|
4061
|
+
"[HardKAS] autoBootstrap ignored for non-simulated network"
|
|
4062
|
+
);
|
|
2091
4063
|
}
|
|
2092
4064
|
} else {
|
|
2093
|
-
if (!
|
|
4065
|
+
if (!fs9.existsSync(hardkasDir)) {
|
|
2094
4066
|
if (options.logger) {
|
|
2095
4067
|
options.logger.info("[HardKAS] Auto-bootstrapping simulated workspace");
|
|
2096
4068
|
}
|
|
2097
|
-
|
|
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 (!
|
|
2107
|
-
throw new HardkasError3(
|
|
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
|
-
|
|
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
|
-
|
|
2186
|
-
|
|
4174
|
+
formatSompiToKas2 as formatSompiToKas,
|
|
4175
|
+
inspectVprogsArtifact,
|
|
4176
|
+
inspectZkProof,
|
|
4177
|
+
parseKasToSompi3 as parseKasToSompi,
|
|
4178
|
+
programmabilityClaims,
|
|
2187
4179
|
signTxPlanArtifact2 as signTxPlanArtifact,
|
|
2188
|
-
|
|
4180
|
+
verifyToccataCorpus,
|
|
4181
|
+
verifyZkCorpus,
|
|
4182
|
+
verifyZkProofLocal,
|
|
4183
|
+
writeArtifact4 as writeArtifact
|
|
2189
4184
|
};
|