@hardkas/sdk 0.8.3-alpha → 0.8.5-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/dist/index.d.ts CHANGED
@@ -283,10 +283,18 @@ declare class HardkasArtifactsManager {
283
283
  private workspace;
284
284
  private cache;
285
285
  constructor(workspace: HardkasWorkspace);
286
+ /**
287
+ * Caches an in-memory artifact.
288
+ */
289
+ cacheArtifact(artifact: any): void;
286
290
  /**
287
291
  * Writes a valid artifact to disk (canonical or custom path).
288
292
  */
289
293
  write(artifact: HardkasArtifactBase, options?: WriteArtifactOptions): Promise<WriteArtifactResult>;
294
+ /**
295
+ * Retrieves an artifact from the in-memory cache.
296
+ */
297
+ getCached(id: string): any;
290
298
  /**
291
299
  * Reads an artifact by path or ID/hash from the workspace.
292
300
  */
@@ -309,6 +317,8 @@ declare class HardkasArtifactsManager {
309
317
  */
310
318
  verify(target: any, options?: {
311
319
  throwOnInvalid?: boolean;
320
+ strict?: boolean;
321
+ enforceMetadata?: boolean;
312
322
  }): Promise<any>;
313
323
  }
314
324
 
package/dist/index.js CHANGED
@@ -216,12 +216,20 @@ var HardkasTx = class {
216
216
  plan: builderPlan,
217
217
  ctx: options.workflowId ? { ...systemRuntimeContext, workflowId: options.workflowId } : systemRuntimeContext
218
218
  });
219
- if (options.policy) {
220
- try {
221
- const pol = await this.sdk.artifacts.read(options.policy);
222
- basePlan.policyRef = pol.contentHash || pol.artifactId || options.policy;
223
- } catch (e) {
224
- basePlan.policyRef = options.policy;
219
+ if (options.policy || options.policies) {
220
+ const inputPolicies = options.policies || (options.policy ? [options.policy] : []);
221
+ const resolvedRefs = [];
222
+ for (const p of inputPolicies) {
223
+ try {
224
+ const pol = await this.sdk.artifacts.read(p);
225
+ resolvedRefs.push(pol.contentHash || pol.artifactId || p);
226
+ } catch (e) {
227
+ resolvedRefs.push(p);
228
+ }
229
+ }
230
+ if (resolvedRefs.length > 0) {
231
+ basePlan.policyRefs = resolvedRefs;
232
+ basePlan.policyRef = resolvedRefs[0];
225
233
  }
226
234
  }
227
235
  if (options.networkProfile) {
@@ -253,6 +261,10 @@ var HardkasTx = class {
253
261
  basePlan.lineage.parentArtifactId = finalHash;
254
262
  basePlan.lineage.rootArtifactId = finalHash;
255
263
  }
264
+ this.sdk.artifacts.cacheArtifact(basePlan);
265
+ if (basePlan.policyRefs && basePlan.policyRefs.length > 0) {
266
+ await this.sdk.artifacts.verify(basePlan, { throwOnInvalid: true, strict: true, enforceMetadata: false });
267
+ }
256
268
  return basePlan;
257
269
  }
258
270
  /**
@@ -260,7 +272,7 @@ var HardkasTx = class {
260
272
  */
261
273
  async sign(plan, account, options) {
262
274
  if (typeof plan === "object" && plan !== null && plan.contentHash) {
263
- await this.sdk.artifacts.verify(plan, { throwOnInvalid: true });
275
+ await this.sdk.artifacts.verify(plan, { throwOnInvalid: true, strict: true, enforceMetadata: false });
264
276
  }
265
277
  let resolvedAccount;
266
278
  if (typeof account === "string") {
@@ -358,7 +370,7 @@ var HardkasTx = class {
358
370
  const hash = calculateContentHash(draft, CURRENT_HASH_VERSION2);
359
371
  draft.signedId = `signed-${hash.slice(0, 16)}`;
360
372
  draft.contentHash = hash;
361
- if (draft.lineage) draft.lineage.artifactId = draft.signedId;
373
+ if (draft.lineage) draft.lineage.artifactId = hash;
362
374
  signedArtifact = draft;
363
375
  } else if (plan.schema === "hardkas.txPlan") {
364
376
  if (options?.append) {
@@ -439,7 +451,7 @@ var HardkasTx = class {
439
451
  const hash = calculateContentHash(draft, CURRENT_HASH_VERSION2);
440
452
  draft.signedId = `signed-${hash.slice(0, 16)}`;
441
453
  draft.contentHash = hash;
442
- if (draft.lineage) draft.lineage.artifactId = draft.signedId;
454
+ if (draft.lineage) draft.lineage.artifactId = hash;
443
455
  signedArtifact = draft;
444
456
  } else {
445
457
  if (resolvedAccount.address !== plan.from.address) {
@@ -482,9 +494,22 @@ var HardkasTx = class {
482
494
  */
483
495
  async simulate(target, options = {}) {
484
496
  if (typeof target === "object" && target !== null && target.contentHash) {
485
- await this.sdk.artifacts.verify(target, { throwOnInvalid: true });
497
+ await this.sdk.artifacts.verify(target, { throwOnInvalid: true, strict: true, enforceMetadata: false });
486
498
  }
487
499
  const persist = options.persist ?? true;
500
+ if (typeof target === "object" && target !== null) {
501
+ const checkTxId = target.txId || (target.schema === ARTIFACT_SCHEMAS.SIGNED_TX ? `simulated-${target.sourcePlanId || "unknown"}-tx` : `simulated-${target.planId || target.id || "unknown"}-tx`);
502
+ if (checkTxId) {
503
+ try {
504
+ const existingReceipt = await this.sdk.artifacts.read(checkTxId, { expectedSchema: ARTIFACT_SCHEMAS.TX_RECEIPT });
505
+ if (existingReceipt && existingReceipt.schema === ARTIFACT_SCHEMAS.TX_RECEIPT) {
506
+ const receiptPath2 = getDefaultReceiptPath(checkTxId, this.sdk.config.cwd);
507
+ return { receipt: existingReceipt, receiptPath: receiptPath2 };
508
+ }
509
+ } catch (e) {
510
+ }
511
+ }
512
+ }
488
513
  const {
489
514
  loadOrCreateLocalnetState,
490
515
  saveLocalnetState,
@@ -515,10 +540,13 @@ var HardkasTx = class {
515
540
  signedId = targetObj.signedId || targetObj.id || "unknown";
516
541
  sourcePlanId = targetObj.sourcePlanId || "unknown";
517
542
  txId = targetObj.txId || `simulated-${sourcePlanId}-tx`;
518
- try {
519
- planArtifact = await this.sdk.artifacts.read(sourcePlanId, { expectedSchema: ARTIFACT_SCHEMAS.TX_PLAN });
520
- } catch (e) {
521
- planArtifact = targetObj;
543
+ planArtifact = this.sdk.artifacts.getCached(sourcePlanId);
544
+ if (!planArtifact) {
545
+ try {
546
+ planArtifact = await this.sdk.artifacts.read(sourcePlanId, { expectedSchema: ARTIFACT_SCHEMAS.TX_PLAN });
547
+ } catch (e) {
548
+ throw new Error("parent_plan_unresolved");
549
+ }
522
550
  }
523
551
  } else {
524
552
  planArtifact = targetObj;
@@ -657,7 +685,7 @@ var HardkasTx = class {
657
685
  */
658
686
  async send(signedArtifact, urlOrOptions) {
659
687
  if (typeof signedArtifact === "object" && signedArtifact !== null && signedArtifact.contentHash) {
660
- await this.sdk.artifacts.verify(signedArtifact, { throwOnInvalid: true });
688
+ await this.sdk.artifacts.verify(signedArtifact, { throwOnInvalid: true, strict: true, enforceMetadata: false });
661
689
  }
662
690
  const verification = verifySignedTxSemantics(signedArtifact);
663
691
  if (!verification.ok) {
@@ -1064,7 +1092,7 @@ var HardkasReplay = class {
1064
1092
  async verify(targetOrOptions, options) {
1065
1093
  const throwOnInvalid = options?.throwOnInvalid !== false;
1066
1094
  if (typeof targetOrOptions === "object" && targetOrOptions !== null && targetOrOptions.contentHash) {
1067
- const verifyRes = await this.sdk.artifacts.verify(targetOrOptions, { throwOnInvalid });
1095
+ const verifyRes = await this.sdk.artifacts.verify(targetOrOptions, { throwOnInvalid, strict: true });
1068
1096
  if (!verifyRes.valid && !throwOnInvalid) {
1069
1097
  return {
1070
1098
  passed: false,
@@ -1324,6 +1352,17 @@ var HardkasArtifactsManager = class {
1324
1352
  }
1325
1353
  workspace;
1326
1354
  cache = /* @__PURE__ */ new Map();
1355
+ /**
1356
+ * Caches an in-memory artifact.
1357
+ */
1358
+ cacheArtifact(artifact) {
1359
+ const record = artifact;
1360
+ const hash = record.contentHash || "unknown";
1361
+ if (record.planId) this.cache.set(record.planId, artifact);
1362
+ if (record.signedId) this.cache.set(record.signedId, artifact);
1363
+ if (record.txId) this.cache.set(record.txId, artifact);
1364
+ this.cache.set(hash, artifact);
1365
+ }
1327
1366
  /**
1328
1367
  * Writes a valid artifact to disk (canonical or custom path).
1329
1368
  */
@@ -1383,17 +1422,16 @@ var HardkasArtifactsManager = class {
1383
1422
  contentHash: hash
1384
1423
  };
1385
1424
  }
1425
+ /**
1426
+ * Retrieves an artifact from the in-memory cache.
1427
+ */
1428
+ getCached(id) {
1429
+ return this.cache.get(id);
1430
+ }
1386
1431
  /**
1387
1432
  * Reads an artifact by path or ID/hash from the workspace.
1388
1433
  */
1389
1434
  async read(id, options) {
1390
- if (this.cache.has(id)) {
1391
- const cached = this.cache.get(id);
1392
- if (options?.expectedSchema && cached.schema !== options.expectedSchema) {
1393
- throw new Error(`Artifact ${id} has schema '${cached.schema}' but expected '${options.expectedSchema}'`);
1394
- }
1395
- return cached;
1396
- }
1397
1435
  const { readArtifact } = await import("@hardkas/artifacts");
1398
1436
  let filePath = id;
1399
1437
  let resolvedPath = path3.resolve(this.workspace.root, filePath);
@@ -1410,7 +1448,27 @@ var HardkasArtifactsManager = class {
1410
1448
  if (!fs3.existsSync(filePath)) {
1411
1449
  if (fs3.existsSync(this.workspace.artifactsDir)) {
1412
1450
  const files = fs3.readdirSync(this.workspace.artifactsDir);
1413
- const found = files.find((f) => f === `${id}.json` || f.startsWith(`${id}-`) || f.startsWith(`${id}.`));
1451
+ let found = files.find(
1452
+ (f) => f === `${id}.json` || f.startsWith(`${id}-`) || f.startsWith(`${id}.`) || f.endsWith(`-${id}.json`) || f.endsWith(`-${id}.plan.json`) || f.endsWith(`-${id}.signed.json`) || f.endsWith(`-${id}.receipt.json`)
1453
+ );
1454
+ if (!found) {
1455
+ const shortId = id.startsWith("plan-") || id.startsWith("signed-") ? id : id.slice(0, 16);
1456
+ for (const file of files) {
1457
+ if (!file.endsWith(".json")) continue;
1458
+ if (file.includes(id) || file.includes(shortId) || file.includes(id.slice(0, 8))) {
1459
+ const fp = path3.join(this.workspace.artifactsDir, file);
1460
+ try {
1461
+ const content = fs3.readFileSync(fp, "utf-8");
1462
+ const obj = JSON.parse(content);
1463
+ if (obj.contentHash === id || obj.artifactId === id || obj.planId === id || obj.signedId === id || obj.txId === id) {
1464
+ found = file;
1465
+ break;
1466
+ }
1467
+ } catch {
1468
+ }
1469
+ }
1470
+ }
1471
+ }
1414
1472
  if (found) {
1415
1473
  filePath = path3.join(this.workspace.artifactsDir, found);
1416
1474
  } else {
@@ -1460,6 +1518,8 @@ var HardkasArtifactsManager = class {
1460
1518
  */
1461
1519
  async verify(target, options = {}) {
1462
1520
  const throwOnInvalid = options.throwOnInvalid ?? true;
1521
+ const strict = options.strict ?? false;
1522
+ const enforceMetadata = options.enforceMetadata ?? true;
1463
1523
  let artifact;
1464
1524
  let id;
1465
1525
  if (typeof target === "string") {
@@ -1478,10 +1538,23 @@ var HardkasArtifactsManager = class {
1478
1538
  artifact = target;
1479
1539
  id = artifact.artifactId || artifact.contentHash || "";
1480
1540
  }
1481
- const { verifyArtifactIntegrity: verifyArtifactIntegrity2 } = await import("@hardkas/artifacts");
1541
+ const { verifyArtifactIntegrity: verifyArtifactIntegrity2, verifyArtifactSemantics } = await import("@hardkas/artifacts");
1482
1542
  const result = await verifyArtifactIntegrity2(artifact);
1543
+ if (result.ok && strict) {
1544
+ const semResult = verifyArtifactSemantics(artifact, {
1545
+ strict: true,
1546
+ artifactsDir: this.workspace.artifactsDir,
1547
+ enforceMetadata,
1548
+ resolveArtifact: (id2) => this.cache.get(id2)
1549
+ });
1550
+ if (!semResult.ok) {
1551
+ result.ok = false;
1552
+ result.errors.push(...semResult.errors);
1553
+ result.issues.push(...semResult.issues);
1554
+ }
1555
+ }
1483
1556
  if (!result.ok) {
1484
- 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" : "schema_invalid";
1557
+ 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 === "PARENT_MISSING" ? "parent_missing" : "schema_invalid";
1485
1558
  if (throwOnInvalid) {
1486
1559
  throw new Error(`Artifact ${id} corrupted or invalid: ` + JSON.stringify(result.issues, null, 2));
1487
1560
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hardkas/sdk",
3
- "version": "0.8.3-alpha",
3
+ "version": "0.8.5-alpha",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",
@@ -23,18 +23,18 @@
23
23
  }
24
24
  },
25
25
  "dependencies": {
26
- "@hardkas/artifacts": "0.8.3-alpha",
27
- "@hardkas/accounts": "0.8.3-alpha",
28
- "@hardkas/kaspa-rpc": "0.8.3-alpha",
29
- "@hardkas/config": "0.8.3-alpha",
30
- "@hardkas/core": "0.8.3-alpha",
31
- "@hardkas/l2": "0.8.3-alpha",
32
- "@hardkas/localnet": "0.8.3-alpha",
33
- "@hardkas/simulator": "0.8.3-alpha",
34
- "@hardkas/wallet-adapter": "0.8.3-alpha",
35
- "@hardkas/query": "0.8.3-alpha",
36
- "@hardkas/tx-builder": "0.8.3-alpha",
37
- "@hardkas/query-store": "0.8.3-alpha"
26
+ "@hardkas/accounts": "0.8.5-alpha",
27
+ "@hardkas/artifacts": "0.8.5-alpha",
28
+ "@hardkas/core": "0.8.5-alpha",
29
+ "@hardkas/l2": "0.8.5-alpha",
30
+ "@hardkas/localnet": "0.8.5-alpha",
31
+ "@hardkas/kaspa-rpc": "0.8.5-alpha",
32
+ "@hardkas/config": "0.8.5-alpha",
33
+ "@hardkas/query": "0.8.5-alpha",
34
+ "@hardkas/simulator": "0.8.5-alpha",
35
+ "@hardkas/tx-builder": "0.8.5-alpha",
36
+ "@hardkas/wallet-adapter": "0.8.5-alpha",
37
+ "@hardkas/query-store": "0.8.5-alpha"
38
38
  },
39
39
  "devDependencies": {
40
40
  "tsup": "^8.3.5",