@hazbase/simplicity 0.0.5 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +645 -148
  2. package/dist/cli.js +2125 -159
  3. package/dist/client/SimplicityClient.d.ts +64 -290
  4. package/dist/client/SimplicityClient.js +65 -23
  5. package/dist/core/executor.js +67 -92
  6. package/dist/core/outputBinding.d.ts +61 -0
  7. package/dist/core/outputBinding.js +552 -0
  8. package/dist/core/schnorr.d.ts +5 -0
  9. package/dist/core/schnorr.js +34 -0
  10. package/dist/core/types.d.ts +553 -1
  11. package/dist/docs/definitions/bond-anchor.simf +19 -0
  12. package/dist/docs/definitions/bond-definition.json +10 -0
  13. package/dist/docs/definitions/bond-descriptor-bound-settlement-machine.simf +144 -0
  14. package/dist/docs/definitions/bond-issuance-anchor.simf +26 -0
  15. package/dist/docs/definitions/bond-issuance-state-partial-redemption.json +18 -0
  16. package/dist/docs/definitions/bond-issuance-state-redeemed.json +18 -0
  17. package/dist/docs/definitions/bond-issuance-state.json +12 -0
  18. package/dist/docs/definitions/bond-redemption-state-machine.simf +118 -0
  19. package/dist/docs/definitions/bond-redemption-transition.simf +41 -0
  20. package/dist/docs/definitions/bond-script-bound-settlement-machine.simf +142 -0
  21. package/dist/docs/definitions/fund-capital-call-open.simf +82 -0
  22. package/dist/docs/definitions/fund-capital-call-refund-only.simf +33 -0
  23. package/dist/docs/definitions/fund-capital-call-state.json +11 -0
  24. package/dist/docs/definitions/fund-definition.json +8 -0
  25. package/dist/docs/definitions/fund-distribution-claim.simf +57 -0
  26. package/dist/docs/definitions/recursive-delay-direct-next.simf +60 -0
  27. package/dist/docs/definitions/recursive-delay-optional.simf +88 -0
  28. package/dist/docs/definitions/recursive-delay-required.simf +72 -0
  29. package/dist/docs/definitions/recursive-delay.simf +83 -0
  30. package/dist/docs/definitions/recursive-policy-transfer-machine.simf +65 -0
  31. package/dist/domain/bond.d.ts +8583 -721
  32. package/dist/domain/bond.js +1272 -31
  33. package/dist/domain/bondSettlementValidation.d.ts +2 -0
  34. package/dist/domain/bondSettlementValidation.js +28 -0
  35. package/dist/domain/bondValidation.d.ts +6 -0
  36. package/dist/domain/bondValidation.js +65 -3
  37. package/dist/domain/fund.d.ts +2069 -0
  38. package/dist/domain/fund.js +1384 -0
  39. package/dist/domain/fundValidation.d.ts +122 -0
  40. package/dist/domain/fundValidation.js +635 -0
  41. package/dist/domain/policies.d.ts +1051 -0
  42. package/dist/domain/policies.js +1605 -0
  43. package/dist/index.d.ts +5 -1
  44. package/dist/index.js +85 -21
  45. package/package.json +15 -2
@@ -40,27 +40,75 @@ exports.defineBond = defineBond;
40
40
  exports.verifyBond = verifyBond;
41
41
  exports.loadBond = loadBond;
42
42
  exports.buildBondPayload = buildBondPayload;
43
+ exports.summarizeExpectedOutputDescriptor = summarizeExpectedOutputDescriptor;
44
+ exports.validateExpectedOutputDescriptor = validateExpectedOutputDescriptor;
45
+ exports.buildExpectedOutputDescriptor = buildExpectedOutputDescriptor;
46
+ exports.verifyExpectedOutputDescriptor = verifyExpectedOutputDescriptor;
43
47
  exports.redeemBond = redeemBond;
44
48
  exports.buildBondTransitionPayload = buildBondTransitionPayload;
45
49
  exports.buildBondSettlementDescriptor = buildBondSettlementDescriptor;
46
50
  exports.verifyBondSettlementDescriptor = verifyBondSettlementDescriptor;
47
51
  exports.buildBondSettlementPayload = buildBondSettlementPayload;
52
+ exports.buildBondClosing = buildBondClosing;
53
+ exports.verifyBondClosing = verifyBondClosing;
54
+ exports.buildEvidenceBundle = buildEvidenceBundle;
55
+ exports.verifyEvidenceBundle = verifyEvidenceBundle;
56
+ exports.issueBond = issueBond;
57
+ exports.prepareRedemption = prepareRedemption;
58
+ exports.finalizeRedemption = finalizeRedemption;
59
+ exports.prepareClosing = prepareClosing;
60
+ exports.exportFinalityPayload = exportFinalityPayload;
61
+ exports.define = define;
62
+ exports.verify = verify;
63
+ exports.load = load;
64
+ exports.issue = issue;
65
+ exports.buildSettlement = buildSettlement;
66
+ exports.verifySettlement = verifySettlement;
67
+ exports.inspectRedemption = inspectRedemption;
68
+ exports.executeRedemption = executeRedemption;
69
+ exports.verifyRedemption = verifyRedemption;
70
+ exports.inspectClosing = inspectClosing;
71
+ exports.executeClosing = executeClosing;
72
+ exports.verifyClosing = verifyClosing;
73
+ exports.exportEvidence = exportEvidence;
48
74
  exports.compileBondTransition = compileBondTransition;
49
75
  exports.verifyBondRedemptionMachineArtifact = verifyBondRedemptionMachineArtifact;
50
76
  exports.compileBondRedemptionMachine = compileBondRedemptionMachine;
77
+ exports.compileBondScriptBoundSettlementMachine = compileBondScriptBoundSettlementMachine;
78
+ exports.verifyBondScriptBoundSettlementMachineArtifact = verifyBondScriptBoundSettlementMachineArtifact;
79
+ exports.compileBondDescriptorBoundSettlementMachine = compileBondDescriptorBoundSettlementMachine;
80
+ exports.verifyBondDescriptorBoundSettlementMachineArtifact = verifyBondDescriptorBoundSettlementMachineArtifact;
81
+ exports.compileBondClosingMachine = compileBondClosingMachine;
51
82
  exports.buildBondRedemption = buildBondRedemption;
52
83
  exports.verifyBondTransition = verifyBondTransition;
53
84
  exports.buildBondRolloverPlan = buildBondRolloverPlan;
54
85
  exports.buildBondMachineRolloverPlan = buildBondMachineRolloverPlan;
86
+ exports.buildBondScriptBoundMachineRolloverPlan = buildBondScriptBoundMachineRolloverPlan;
87
+ exports.buildBondDescriptorBoundMachineRolloverPlan = buildBondDescriptorBoundMachineRolloverPlan;
55
88
  exports.buildBondMachineSettlementPlan = buildBondMachineSettlementPlan;
89
+ exports.buildBondScriptBoundMachineSettlementPlan = buildBondScriptBoundMachineSettlementPlan;
90
+ exports.buildBondDescriptorBoundMachineSettlementPlan = buildBondDescriptorBoundMachineSettlementPlan;
56
91
  exports.inspectBondStateRollover = inspectBondStateRollover;
57
92
  exports.inspectBondMachineRollover = inspectBondMachineRollover;
93
+ exports.inspectBondScriptBoundMachineRollover = inspectBondScriptBoundMachineRollover;
94
+ exports.inspectBondDescriptorBoundMachineRollover = inspectBondDescriptorBoundMachineRollover;
58
95
  exports.inspectBondMachineSettlement = inspectBondMachineSettlement;
96
+ exports.inspectBondScriptBoundMachineSettlement = inspectBondScriptBoundMachineSettlement;
97
+ exports.inspectBondDescriptorBoundMachineSettlement = inspectBondDescriptorBoundMachineSettlement;
98
+ exports.buildBondClosingPlan = buildBondClosingPlan;
59
99
  exports.executeBondStateRollover = executeBondStateRollover;
60
100
  exports.executeBondMachineRollover = executeBondMachineRollover;
101
+ exports.executeBondScriptBoundMachineRollover = executeBondScriptBoundMachineRollover;
102
+ exports.executeBondDescriptorBoundMachineRollover = executeBondDescriptorBoundMachineRollover;
61
103
  exports.executeBondMachineSettlement = executeBondMachineSettlement;
104
+ exports.executeBondScriptBoundMachineSettlement = executeBondScriptBoundMachineSettlement;
105
+ exports.executeBondDescriptorBoundMachineSettlement = executeBondDescriptorBoundMachineSettlement;
106
+ exports.inspectBondClosing = inspectBondClosing;
107
+ exports.executeBondClosing = executeBondClosing;
108
+ const node_fs_1 = require("node:fs");
62
109
  const node_path_1 = __importDefault(require("node:path"));
63
110
  const summary_1 = require("../core/summary");
111
+ const outputBinding_1 = require("../core/outputBinding");
64
112
  const bondSettlementValidation_1 = require("./bondSettlementValidation");
65
113
  const bondValidation_1 = require("./bondValidation");
66
114
  function resolveValueOrPath(options) {
@@ -70,6 +118,18 @@ function resolveValueOrPath(options) {
70
118
  return { value: options.objectValue };
71
119
  return {};
72
120
  }
121
+ function resolveBondDocsAsset(filename) {
122
+ const cwdCandidate = node_path_1.default.resolve(process.cwd(), "docs/definitions", filename);
123
+ if ((0, node_fs_1.existsSync)(cwdCandidate)) {
124
+ return cwdCandidate;
125
+ }
126
+ // In published packages we copy bond example contracts into dist/docs/definitions.
127
+ const bundledCandidate = node_path_1.default.resolve(__dirname, "../docs/definitions", filename);
128
+ if ((0, node_fs_1.existsSync)(bundledCandidate)) {
129
+ return bundledCandidate;
130
+ }
131
+ return cwdCandidate;
132
+ }
73
133
  async function defineBond(sdk, input) {
74
134
  const definitionSource = resolveValueOrPath({
75
135
  pathValue: input.definitionPath,
@@ -102,7 +162,7 @@ async function defineBond(sdk, input) {
102
162
  ...(issuanceSource.jsonPath ? { jsonPath: issuanceSource.jsonPath } : { value: issuance }),
103
163
  });
104
164
  (0, bondValidation_1.validateBondCrossChecks)(definition, issuance);
105
- const simfPath = input.simfPath ?? node_path_1.default.resolve(process.cwd(), "docs/definitions/bond-issuance-anchor.simf");
165
+ const simfPath = input.simfPath ?? resolveBondDocsAsset("bond-issuance-anchor.simf");
106
166
  return sdk.compileFromFile({
107
167
  simfPath,
108
168
  templateVars: {
@@ -263,12 +323,223 @@ function bondStatusToCode(status) {
263
323
  return 2;
264
324
  case "REDEEMED":
265
325
  return 3;
326
+ case "CLOSED":
327
+ return 4;
266
328
  default: {
267
329
  const exhaustiveCheck = status;
268
330
  throw new Error(`Unsupported bond status: ${exhaustiveCheck}`);
269
331
  }
270
332
  }
271
333
  }
334
+ function closingReasonToCode(reason) {
335
+ switch (reason) {
336
+ case "REDEEMED":
337
+ return 1;
338
+ case "CANCELLED":
339
+ return 2;
340
+ case "MATURED_OUT":
341
+ return 3;
342
+ default: {
343
+ const exhaustiveCheck = reason;
344
+ throw new Error(`Unsupported closing reason: ${exhaustiveCheck}`);
345
+ }
346
+ }
347
+ }
348
+ function summarizeExpectedOutputDescriptor(descriptor) {
349
+ const canonicalJson = (0, summary_1.stableStringify)({
350
+ assetId: descriptor.assetId,
351
+ feeIndex: descriptor.feeIndex,
352
+ maxFeeSat: descriptor.maxFeeSat,
353
+ nextAmountSat: descriptor.nextAmountSat,
354
+ nextContractAddress: descriptor.nextContractAddress,
355
+ nextOutputHash: descriptor.nextOutputHash ?? null,
356
+ nextOutputScriptHash: descriptor.nextOutputScriptHash ?? null,
357
+ nextOutputIndex: descriptor.nextOutputIndex,
358
+ requestedOutputBindingMode: descriptor.requestedOutputBindingMode ?? descriptor.outputBindingMode ?? "none",
359
+ outputForm: descriptor.outputForm ?? (0, outputBinding_1.normalizeOutputForm)(),
360
+ rawOutput: (0, outputBinding_1.normalizeOutputRawFields)(descriptor.rawOutput) ?? null,
361
+ outputBindingMode: descriptor.outputBindingMode ?? "none",
362
+ });
363
+ return { canonicalJson, hash: (0, summary_1.sha256HexUtf8)(canonicalJson) };
364
+ }
365
+ function validateExpectedOutputDescriptor(descriptor) {
366
+ if (!descriptor.nextContractAddress || descriptor.nextContractAddress.trim().length === 0) {
367
+ throw new Error("nextContractAddress must be a non-empty string");
368
+ }
369
+ if (!descriptor.assetId || descriptor.assetId.trim().length === 0) {
370
+ throw new Error("assetId must be a non-empty string");
371
+ }
372
+ if (descriptor.nextOutputScriptHash !== undefined && descriptor.nextOutputScriptHash !== null) {
373
+ if (!/^[0-9a-f]{64}$/i.test(descriptor.nextOutputScriptHash)) {
374
+ throw new Error("nextOutputScriptHash must be a 64-character hex string");
375
+ }
376
+ }
377
+ if (descriptor.nextOutputHash !== undefined && descriptor.nextOutputHash !== null) {
378
+ if (!/^[0-9a-f]{64}$/i.test(descriptor.nextOutputHash)) {
379
+ throw new Error("nextOutputHash must be a 64-character hex string");
380
+ }
381
+ }
382
+ if (!Number.isInteger(descriptor.nextAmountSat) || descriptor.nextAmountSat <= 0) {
383
+ throw new Error("nextAmountSat must be a positive integer");
384
+ }
385
+ if (!Number.isInteger(descriptor.maxFeeSat) || descriptor.maxFeeSat < 0) {
386
+ throw new Error("maxFeeSat must be a non-negative integer");
387
+ }
388
+ if (!Number.isInteger(descriptor.nextOutputIndex) || descriptor.nextOutputIndex < 0) {
389
+ throw new Error("nextOutputIndex must be a non-negative integer");
390
+ }
391
+ if (!Number.isInteger(descriptor.feeIndex) || descriptor.feeIndex < 0) {
392
+ throw new Error("feeIndex must be a non-negative integer");
393
+ }
394
+ if (descriptor.requestedOutputBindingMode
395
+ && descriptor.requestedOutputBindingMode !== "none"
396
+ && descriptor.requestedOutputBindingMode !== "script-bound"
397
+ && descriptor.requestedOutputBindingMode !== "descriptor-bound") {
398
+ throw new Error("requestedOutputBindingMode must be none, script-bound, or descriptor-bound");
399
+ }
400
+ if (descriptor.outputBindingMode !== "none"
401
+ && descriptor.outputBindingMode !== "script-bound"
402
+ && descriptor.outputBindingMode !== "descriptor-bound") {
403
+ throw new Error("outputBindingMode must be none, script-bound, or descriptor-bound");
404
+ }
405
+ descriptor.rawOutput = (0, outputBinding_1.normalizeOutputRawFields)(descriptor.rawOutput);
406
+ descriptor.outputForm = (0, outputBinding_1.normalizeOutputForm)(descriptor.outputForm);
407
+ descriptor.requestedOutputBindingMode = descriptor.requestedOutputBindingMode ?? descriptor.outputBindingMode ?? "none";
408
+ return descriptor;
409
+ }
410
+ async function buildExpectedOutputDescriptor(sdk, input) {
411
+ const definitionSource = resolveValueOrPath({
412
+ pathValue: input.definitionPath,
413
+ objectValue: input.definitionValue,
414
+ });
415
+ const nextSource = resolveValueOrPath({
416
+ pathValue: input.nextIssuancePath,
417
+ objectValue: input.nextIssuanceValue,
418
+ });
419
+ const definitionDescriptor = await sdk.loadDefinition({
420
+ type: "bond",
421
+ id: input.definitionValue?.bondId ?? "BOND-2026-001",
422
+ ...definitionSource,
423
+ });
424
+ const nextDescriptor = await sdk.loadStateDocument({
425
+ type: "bond-issuance",
426
+ id: input.nextIssuanceValue?.issuanceId ?? "BOND-2026-001-ISSUE-1",
427
+ ...nextSource,
428
+ });
429
+ const definition = (0, bondValidation_1.validateBondDefinition)(JSON.parse(definitionDescriptor.canonicalJson));
430
+ const next = (0, bondValidation_1.validateBondIssuanceState)(JSON.parse(nextDescriptor.canonicalJson));
431
+ (0, bondValidation_1.validateBondCrossChecks)(definition, next);
432
+ const nextStateCompiled = await defineBond(sdk, {
433
+ definitionValue: definition,
434
+ issuanceValue: next,
435
+ simfPath: input.nextStateSimfPath,
436
+ });
437
+ const nextScriptPubKeyHex = await (0, outputBinding_1.getScriptPubKeyHexViaRpc)(sdk, nextStateCompiled.deployment().contractAddress);
438
+ const nextOutputScriptHash = (0, outputBinding_1.hashHexBytes)(nextScriptPubKeyHex);
439
+ const requestedBindingMode = input.outputBindingMode ?? "script-bound";
440
+ const outputForm = (0, outputBinding_1.normalizeOutputForm)(input.outputForm);
441
+ const rawOutput = (0, outputBinding_1.normalizeOutputRawFields)(input.rawOutput);
442
+ const rawOutputAnalysis = (0, outputBinding_1.analyzeOutputRawFields)(rawOutput);
443
+ const explicitAssetHex = requestedBindingMode !== "none" && (0, outputBinding_1.isExplicitV1OutputForm)(outputForm)
444
+ ? await (0, outputBinding_1.resolveExplicitAssetHex)(sdk, definition.currencyAssetId)
445
+ : undefined;
446
+ const autoDerivedNextOutputHash = requestedBindingMode === "descriptor-bound" && !input.nextOutputHash
447
+ ? rawOutputAnalysis.valid && rawOutputAnalysis.normalized
448
+ ? (0, outputBinding_1.computeRawOutputV1Hash)(rawOutputAnalysis.normalized)
449
+ : explicitAssetHex
450
+ ? (0, outputBinding_1.computeExplicitV1OutputHash)({
451
+ assetHex: explicitAssetHex,
452
+ nextAmountSat: input.nextAmountSat,
453
+ nextOutputScriptHash,
454
+ })
455
+ : undefined
456
+ : undefined;
457
+ const nextOutputHash = input.nextOutputHash ?? autoDerivedNextOutputHash;
458
+ const bindingDecision = (0, outputBinding_1.resolveOutputBindingDecision)({
459
+ requestedBindingMode,
460
+ nextOutputHash,
461
+ nextOutputScriptHash,
462
+ autoDerivedNextOutputHash: Boolean(autoDerivedNextOutputHash && !input.nextOutputHash),
463
+ explicitAssetSupported: Boolean(explicitAssetHex),
464
+ outputForm,
465
+ rawOutput,
466
+ });
467
+ const descriptor = validateExpectedOutputDescriptor({
468
+ nextContractAddress: nextStateCompiled.deployment().contractAddress,
469
+ nextOutputHash: bindingDecision.outputBindingMode === "descriptor-bound" ? nextOutputHash : undefined,
470
+ nextOutputScriptHash: bindingDecision.outputBindingMode !== "none" ? nextOutputScriptHash : undefined,
471
+ nextAmountSat: input.nextAmountSat,
472
+ assetId: definition.currencyAssetId,
473
+ requestedOutputBindingMode: requestedBindingMode,
474
+ outputForm,
475
+ rawOutput,
476
+ feeIndex: input.feeIndex ?? 1,
477
+ nextOutputIndex: input.nextOutputIndex ?? 0,
478
+ maxFeeSat: input.maxFeeSat ?? 100,
479
+ outputBindingMode: bindingDecision.outputBindingMode,
480
+ });
481
+ const summary = summarizeExpectedOutputDescriptor(descriptor);
482
+ return {
483
+ descriptor,
484
+ canonicalJson: summary.canonicalJson,
485
+ hash: summary.hash,
486
+ supportedForm: bindingDecision.supportedForm,
487
+ reasonCode: bindingDecision.reasonCode,
488
+ autoDerivedNextOutputHash: bindingDecision.autoDerived,
489
+ fallbackReason: bindingDecision.fallbackReason,
490
+ bindingInputs: {
491
+ assetId: descriptor.assetId,
492
+ assetForm: descriptor.outputForm?.assetForm ?? "explicit",
493
+ amountForm: descriptor.outputForm?.amountForm ?? "explicit",
494
+ nonceForm: descriptor.outputForm?.nonceForm ?? "null",
495
+ rangeProofForm: descriptor.outputForm?.rangeProofForm ?? "empty",
496
+ nextAmountSat: descriptor.nextAmountSat,
497
+ nextOutputIndex: descriptor.nextOutputIndex,
498
+ feeIndex: descriptor.feeIndex,
499
+ maxFeeSat: descriptor.maxFeeSat,
500
+ ...(rawOutputAnalysis.valid && rawOutputAnalysis.normalized
501
+ ? {
502
+ rawOutputComponents: {
503
+ scriptPubKey: rawOutputAnalysis.normalized.scriptComponentSource,
504
+ rangeProof: rawOutputAnalysis.normalized.rangeProofComponentSource,
505
+ },
506
+ }
507
+ : {}),
508
+ },
509
+ };
510
+ }
511
+ async function verifyExpectedOutputDescriptor(sdk, input) {
512
+ const actual = validateExpectedOutputDescriptor(input.descriptorValue);
513
+ const expected = await buildExpectedOutputDescriptor(sdk, {
514
+ definitionPath: input.definitionPath,
515
+ definitionValue: input.definitionValue,
516
+ nextIssuancePath: input.nextIssuancePath,
517
+ nextIssuanceValue: input.nextIssuanceValue,
518
+ nextStateSimfPath: input.nextStateSimfPath,
519
+ nextAmountSat: input.nextAmountSat ?? actual.nextAmountSat,
520
+ maxFeeSat: input.maxFeeSat ?? actual.maxFeeSat,
521
+ nextOutputIndex: input.nextOutputIndex ?? actual.nextOutputIndex,
522
+ feeIndex: input.feeIndex ?? actual.feeIndex,
523
+ nextOutputHash: input.nextOutputHash ?? actual.nextOutputHash,
524
+ outputForm: input.outputForm ?? actual.outputForm,
525
+ rawOutput: input.rawOutput ?? actual.rawOutput,
526
+ outputBindingMode: input.outputBindingMode ?? actual.outputBindingMode,
527
+ });
528
+ const actualSummary = summarizeExpectedOutputDescriptor(actual);
529
+ return {
530
+ ok: actualSummary.hash === expected.hash,
531
+ reason: actualSummary.hash === expected.hash ? undefined : "Expected output descriptor hash mismatch",
532
+ descriptor: actual,
533
+ expected: expected.descriptor,
534
+ hash: actualSummary.hash,
535
+ expectedHash: expected.hash,
536
+ supportedForm: expected.supportedForm,
537
+ reasonCode: expected.reasonCode,
538
+ autoDerivedNextOutputHash: expected.autoDerivedNextOutputHash,
539
+ fallbackReason: expected.fallbackReason,
540
+ bindingInputs: expected.bindingInputs,
541
+ };
542
+ }
272
543
  async function redeemBond(sdk, input) {
273
544
  const definitionSource = resolveValueOrPath({
274
545
  pathValue: input.definitionPath,
@@ -307,7 +578,7 @@ async function redeemBond(sdk, input) {
307
578
  id: nextIssuance.issuanceId,
308
579
  value: nextIssuance,
309
580
  });
310
- const simfPath = input.simfPath ?? node_path_1.default.resolve(process.cwd(), "docs/definitions/bond-issuance-anchor.simf");
581
+ const simfPath = input.simfPath ?? resolveBondDocsAsset("bond-issuance-anchor.simf");
311
582
  return sdk.compileFromFile({
312
583
  simfPath,
313
584
  templateVars: {
@@ -413,6 +684,17 @@ async function buildBondSettlementDescriptor(sdk, input) {
413
684
  issuanceValue: transition.next,
414
685
  simfPath: input.nextStateSimfPath,
415
686
  });
687
+ const expectedOutputDescriptor = await buildExpectedOutputDescriptor(sdk, {
688
+ definitionValue: transition.definition,
689
+ nextIssuanceValue: transition.next,
690
+ nextStateSimfPath: input.nextStateSimfPath,
691
+ nextAmountSat: input.nextAmountSat,
692
+ maxFeeSat: input.maxFeeSat ?? 100,
693
+ nextOutputHash: input.nextOutputHash,
694
+ outputForm: input.outputForm,
695
+ rawOutput: input.rawOutput,
696
+ outputBindingMode: input.outputBindingMode,
697
+ });
416
698
  const nextContractAddress = nextStateCompiled.deployment().contractAddress;
417
699
  const descriptor = (0, bondSettlementValidation_1.validateBondSettlementDescriptor)({
418
700
  settlementId: `${transition.previous.issuanceId}-SETTLEMENT-${transition.payload.nextStatus}`,
@@ -430,6 +712,8 @@ async function buildBondSettlementDescriptor(sdk, input) {
430
712
  nextContractAddress,
431
713
  nextAmountSat: input.nextAmountSat,
432
714
  maxFeeSat: input.maxFeeSat ?? 100,
715
+ expectedOutputDescriptorHash: expectedOutputDescriptor.hash,
716
+ outputBindingMode: expectedOutputDescriptor.descriptor.outputBindingMode ?? "none",
433
717
  principal: {
434
718
  issued: transition.payload.principal.issued,
435
719
  previousOutstanding: transition.payload.principal.previousOutstanding,
@@ -446,6 +730,13 @@ async function buildBondSettlementDescriptor(sdk, input) {
446
730
  transition: transition.payload.crossChecks.transition,
447
731
  nextContractAddress,
448
732
  descriptor,
733
+ expectedOutputDescriptor: expectedOutputDescriptor.descriptor,
734
+ expectedOutputDescriptorHash: expectedOutputDescriptor.hash,
735
+ expectedOutputBindingSupportedForm: expectedOutputDescriptor.supportedForm,
736
+ expectedOutputBindingReasonCode: expectedOutputDescriptor.reasonCode,
737
+ expectedOutputBindingAutoDerived: expectedOutputDescriptor.autoDerivedNextOutputHash,
738
+ expectedOutputBindingFallbackReason: expectedOutputDescriptor.fallbackReason,
739
+ expectedOutputBindingInputs: expectedOutputDescriptor.bindingInputs,
449
740
  canonicalJson: summary.canonicalJson,
450
741
  hash: summary.hash,
451
742
  };
@@ -468,6 +759,10 @@ async function verifyBondSettlementDescriptor(sdk, input) {
468
759
  nextStateSimfPath: input.nextStateSimfPath,
469
760
  nextAmountSat: input.nextAmountSat ?? descriptor.nextAmountSat,
470
761
  maxFeeSat: input.maxFeeSat ?? descriptor.maxFeeSat,
762
+ nextOutputHash: input.nextOutputHash,
763
+ outputForm: input.outputForm,
764
+ rawOutput: input.rawOutput,
765
+ outputBindingMode: descriptor.outputBindingMode,
471
766
  });
472
767
  const actualSummary = (0, bondSettlementValidation_1.summarizeBondSettlementDescriptor)(descriptor);
473
768
  const matches = (0, bondSettlementValidation_1.validateBondSettlementMatchesExpected)(descriptor, expected.descriptor);
@@ -479,6 +774,11 @@ async function verifyBondSettlementDescriptor(sdk, input) {
479
774
  hash: actualSummary.hash,
480
775
  expectedHash: expected.hash,
481
776
  matches,
777
+ supportedForm: expected.expectedOutputBindingSupportedForm,
778
+ reasonCode: expected.expectedOutputBindingReasonCode,
779
+ autoDerivedNextOutputHash: expected.expectedOutputBindingAutoDerived,
780
+ fallbackReason: expected.expectedOutputBindingFallbackReason,
781
+ bindingInputs: expected.expectedOutputBindingInputs,
482
782
  };
483
783
  }
484
784
  async function buildBondSettlementPayload(sdk, input) {
@@ -486,6 +786,13 @@ async function buildBondSettlementPayload(sdk, input) {
486
786
  return {
487
787
  descriptor: result.descriptor,
488
788
  descriptorHash: result.hash,
789
+ expectedOutputDescriptor: result.expectedOutputDescriptor,
790
+ expectedOutputDescriptorHash: result.expectedOutputDescriptorHash,
791
+ supportedForm: result.expectedOutputBindingSupportedForm,
792
+ reasonCode: result.expectedOutputBindingReasonCode,
793
+ autoDerivedNextOutputHash: result.expectedOutputBindingAutoDerived,
794
+ fallbackReason: result.expectedOutputBindingFallbackReason,
795
+ bindingInputs: result.expectedOutputBindingInputs,
489
796
  previousStateHash: result.descriptor.previousStateHash,
490
797
  nextStateHash: result.descriptor.nextStateHash,
491
798
  nextContractAddress: result.descriptor.nextContractAddress,
@@ -493,6 +800,429 @@ async function buildBondSettlementPayload(sdk, input) {
493
800
  maxFeeSat: result.descriptor.maxFeeSat,
494
801
  };
495
802
  }
803
+ async function buildBondClosing(sdk, input) {
804
+ const definitionSource = resolveValueOrPath({
805
+ pathValue: input.definitionPath,
806
+ objectValue: input.definitionValue,
807
+ });
808
+ const issuanceSource = resolveValueOrPath({
809
+ pathValue: input.redeemedIssuancePath,
810
+ objectValue: input.redeemedIssuanceValue,
811
+ });
812
+ const definitionDescriptor = await sdk.loadDefinition({
813
+ type: "bond",
814
+ id: input.definitionValue?.bondId ?? "BOND-2026-001",
815
+ ...definitionSource,
816
+ });
817
+ const issuanceDescriptor = await sdk.loadStateDocument({
818
+ type: "bond-issuance",
819
+ id: input.redeemedIssuanceValue?.issuanceId ?? "BOND-2026-001-ISSUE-1",
820
+ ...issuanceSource,
821
+ });
822
+ const definition = (0, bondValidation_1.validateBondDefinition)(JSON.parse(definitionDescriptor.canonicalJson));
823
+ const redeemed = (0, bondValidation_1.validateBondIssuanceState)(JSON.parse(issuanceDescriptor.canonicalJson));
824
+ (0, bondValidation_1.validateBondCrossChecks)(definition, redeemed);
825
+ const settlementVerification = await verifyBondSettlementDescriptor(sdk, {
826
+ descriptorPath: input.settlementDescriptorPath,
827
+ descriptorValue: input.settlementDescriptorValue,
828
+ definitionValue: definition,
829
+ previousIssuanceValue: undefined,
830
+ nextIssuanceValue: redeemed,
831
+ nextAmountSat: input.settlementDescriptorValue?.nextAmountSat,
832
+ maxFeeSat: input.settlementDescriptorValue?.maxFeeSat,
833
+ }).catch(() => undefined);
834
+ const finalSettlementDescriptorHash = settlementVerification?.hash
835
+ ?? (input.settlementDescriptorValue
836
+ ? (0, bondSettlementValidation_1.summarizeBondSettlementDescriptor)(input.settlementDescriptorValue).hash
837
+ : undefined);
838
+ if (!finalSettlementDescriptorHash) {
839
+ throw new Error("A valid settlement descriptor is required to build a closing state");
840
+ }
841
+ const closed = (0, bondValidation_1.buildClosedBondIssuanceState)({
842
+ previous: redeemed,
843
+ closedAt: input.closedAt,
844
+ closingReason: input.closingReason ?? "REDEEMED",
845
+ finalSettlementDescriptorHash,
846
+ });
847
+ const closing = {
848
+ closingId: `${closed.issuanceId}-CLOSE`,
849
+ bondId: definition.bondId,
850
+ issuanceId: closed.issuanceId,
851
+ finalStatus: "CLOSED",
852
+ definitionHash: definitionDescriptor.hash,
853
+ previousStateHash: (0, bondValidation_1.summarizeBondIssuanceState)(redeemed).hash,
854
+ closedStateHash: (0, bondValidation_1.summarizeBondIssuanceState)(closed).hash,
855
+ stateHash: (0, bondValidation_1.summarizeBondIssuanceState)(closed).hash,
856
+ closedAt: input.closedAt,
857
+ closingReason: input.closingReason ?? "REDEEMED",
858
+ finalSettlementDescriptorHash,
859
+ };
860
+ return {
861
+ definition,
862
+ previous: redeemed,
863
+ closed,
864
+ closing,
865
+ closingHash: (0, summary_1.sha256HexUtf8)((0, summary_1.stableStringify)(closing)),
866
+ };
867
+ }
868
+ async function verifyBondClosing(sdk, input) {
869
+ const definitionSource = resolveValueOrPath({
870
+ pathValue: input.definitionPath,
871
+ objectValue: input.definitionValue,
872
+ });
873
+ const redeemedSource = resolveValueOrPath({
874
+ pathValue: input.redeemedIssuancePath,
875
+ objectValue: input.redeemedIssuanceValue,
876
+ });
877
+ const closedSource = resolveValueOrPath({
878
+ pathValue: input.closedIssuancePath,
879
+ objectValue: input.closedIssuanceValue,
880
+ });
881
+ const definitionDescriptor = await sdk.loadDefinition({
882
+ type: "bond",
883
+ id: input.definitionValue?.bondId ?? "BOND-2026-001",
884
+ ...definitionSource,
885
+ });
886
+ const redeemedDescriptor = await sdk.loadStateDocument({
887
+ type: "bond-issuance",
888
+ id: input.redeemedIssuanceValue?.issuanceId ?? "BOND-2026-001-ISSUE-1",
889
+ ...redeemedSource,
890
+ });
891
+ const closedDescriptor = await sdk.loadStateDocument({
892
+ type: "bond-issuance",
893
+ id: input.closedIssuanceValue?.issuanceId ?? "BOND-2026-001-ISSUE-1",
894
+ ...closedSource,
895
+ });
896
+ const definition = (0, bondValidation_1.validateBondDefinition)(JSON.parse(definitionDescriptor.canonicalJson));
897
+ const redeemed = (0, bondValidation_1.validateBondIssuanceState)(JSON.parse(redeemedDescriptor.canonicalJson));
898
+ const closed = (0, bondValidation_1.validateBondIssuanceState)(JSON.parse(closedDescriptor.canonicalJson));
899
+ (0, bondValidation_1.validateBondCrossChecks)(definition, redeemed);
900
+ (0, bondValidation_1.validateBondCrossChecks)(definition, closed);
901
+ const settlementHash = input.settlementDescriptorValue
902
+ ? (0, bondSettlementValidation_1.summarizeBondSettlementDescriptor)(input.settlementDescriptorValue).hash
903
+ : input.settlementDescriptorPath
904
+ ? (0, bondSettlementValidation_1.summarizeBondSettlementDescriptor)(JSON.parse(await Promise.resolve().then(() => __importStar(require("node:fs/promises"))).then((fs) => fs.readFile(input.settlementDescriptorPath, "utf8")))).hash
905
+ : "";
906
+ const checks = {
907
+ redeemedStateMatch: redeemed.status === "REDEEMED",
908
+ closedStateMatch: closed.status === "CLOSED",
909
+ previousStateHashMatch: closed.previousStateHash === (0, bondValidation_1.summarizeBondIssuanceState)(redeemed).hash,
910
+ finalSettlementDescriptorHashMatch: closed.finalSettlementDescriptorHash === settlementHash,
911
+ closingReasonPresent: !!closed.closingReason,
912
+ closedAtPresent: !!closed.closedAt,
913
+ };
914
+ return {
915
+ definition,
916
+ redeemed,
917
+ closed,
918
+ checks,
919
+ verified: Object.values(checks).every(Boolean),
920
+ };
921
+ }
922
+ async function buildEvidenceBundle(sdk, input) {
923
+ const artifact = input.artifact ?? (input.artifactPath ? (await sdk.loadArtifact(input.artifactPath)).artifact : undefined);
924
+ if (!artifact)
925
+ throw new Error("artifactPath or artifact is required");
926
+ const verification = await verifyBond(sdk, {
927
+ artifact,
928
+ definitionPath: input.definitionPath,
929
+ definitionValue: input.definitionValue,
930
+ issuancePath: input.issuancePath,
931
+ issuanceValue: input.issuanceValue,
932
+ });
933
+ const definition = verification.definition.definition;
934
+ const issuance = verification.issuance.state;
935
+ const settlementCanonicalJson = input.settlementDescriptorValue
936
+ ? (0, bondSettlementValidation_1.summarizeBondSettlementDescriptor)(input.settlementDescriptorValue).canonicalJson
937
+ : null;
938
+ const settlementHash = input.settlementDescriptorValue
939
+ ? (0, bondSettlementValidation_1.summarizeBondSettlementDescriptor)(input.settlementDescriptorValue).hash
940
+ : null;
941
+ const closingCanonicalJson = input.closingDescriptorValue
942
+ ? (0, summary_1.stableStringify)(input.closingDescriptorValue)
943
+ : null;
944
+ const closingHash = closingCanonicalJson
945
+ ? (0, summary_1.sha256HexUtf8)(closingCanonicalJson)
946
+ : null;
947
+ const sourcePath = artifact.source.mode === "file" ? artifact.source.simfPath : undefined;
948
+ const renderedSourceHash = sourcePath && (0, node_fs_1.existsSync)(sourcePath)
949
+ ? (0, summary_1.sha256HexUtf8)(await Promise.resolve().then(() => __importStar(require("node:fs/promises"))).then((fs) => fs.readFile(sourcePath, "utf8")))
950
+ : null;
951
+ return {
952
+ artifact,
953
+ definition: {
954
+ canonicalJson: definition.canonicalJson,
955
+ hash: definition.hash,
956
+ },
957
+ issuance: {
958
+ canonicalJson: issuance.canonicalJson,
959
+ hash: issuance.hash,
960
+ },
961
+ transition: input.transitionValue
962
+ ? {
963
+ canonicalJson: (0, summary_1.stableStringify)(input.transitionValue),
964
+ hash: (0, summary_1.sha256HexUtf8)((0, summary_1.stableStringify)(input.transitionValue)),
965
+ }
966
+ : undefined,
967
+ settlement: settlementCanonicalJson && settlementHash
968
+ ? {
969
+ canonicalJson: settlementCanonicalJson,
970
+ hash: settlementHash,
971
+ }
972
+ : undefined,
973
+ closing: closingCanonicalJson && closingHash
974
+ ? {
975
+ canonicalJson: closingCanonicalJson,
976
+ hash: closingHash,
977
+ }
978
+ : undefined,
979
+ trust: {
980
+ artifactTrust: {
981
+ definition: verification.definition.trust,
982
+ state: verification.issuance.trust,
983
+ },
984
+ stateTrust: verification.issuance.trust,
985
+ settlementTrust: input.settlementDescriptorValue
986
+ ? {
987
+ descriptorHashMatch: true,
988
+ outputBindingMode: input.settlementDescriptorValue.outputBindingMode ?? "none",
989
+ }
990
+ : undefined,
991
+ },
992
+ renderedSourceHash: renderedSourceHash ?? undefined,
993
+ sourceVerificationMode: renderedSourceHash ? "source-reloaded" : "artifact-only",
994
+ compiled: {
995
+ program: artifact.compiled.program,
996
+ cmr: artifact.compiled.cmr,
997
+ contractAddress: artifact.compiled.contractAddress,
998
+ },
999
+ };
1000
+ }
1001
+ async function verifyEvidenceBundle(sdk, input) {
1002
+ const expected = await buildEvidenceBundle(sdk, {
1003
+ artifact: input.bundleValue.artifact,
1004
+ definitionPath: input.definitionPath,
1005
+ issuancePath: input.issuancePath,
1006
+ settlementDescriptorValue: input.settlementDescriptorValue,
1007
+ closingDescriptorValue: input.closingDescriptorValue,
1008
+ });
1009
+ const checks = {
1010
+ definitionHashMatch: input.bundleValue.definition.hash === expected.definition.hash,
1011
+ issuanceHashMatch: input.bundleValue.issuance.hash === expected.issuance.hash,
1012
+ settlementHashMatch: (input.bundleValue.settlement?.hash ?? null) === (expected.settlement?.hash ?? null),
1013
+ closingHashMatch: (input.bundleValue.closing?.hash ?? null) === (expected.closing?.hash ?? null),
1014
+ renderedSourceHashMatch: input.bundleValue.renderedSourceHash === expected.renderedSourceHash,
1015
+ cmrMatch: input.bundleValue.compiled.cmr === expected.compiled.cmr,
1016
+ contractAddressMatch: input.bundleValue.compiled.contractAddress === expected.compiled.contractAddress,
1017
+ };
1018
+ return {
1019
+ expected,
1020
+ checks,
1021
+ verified: Object.values(checks).every(Boolean),
1022
+ };
1023
+ }
1024
+ async function issueBond(sdk, input) {
1025
+ return defineBond(sdk, input);
1026
+ }
1027
+ async function prepareRedemption(sdk, input) {
1028
+ const preview = await buildBondRedemption(sdk, {
1029
+ definitionPath: input.definitionPath,
1030
+ definitionValue: input.definitionValue,
1031
+ previousIssuancePath: input.previousIssuancePath,
1032
+ previousIssuanceValue: input.previousIssuanceValue,
1033
+ amount: input.amount,
1034
+ redeemedAt: input.redeemedAt,
1035
+ });
1036
+ const settlement = await buildBondSettlementPayload(sdk, {
1037
+ definitionValue: preview.definition,
1038
+ previousIssuanceValue: preview.previous,
1039
+ nextIssuanceValue: preview.next,
1040
+ nextStateSimfPath: input.nextStateSimfPath,
1041
+ nextAmountSat: input.nextAmountSat,
1042
+ maxFeeSat: input.maxFeeSat,
1043
+ nextOutputHash: input.nextOutputHash,
1044
+ rawOutput: input.rawOutput,
1045
+ outputBindingMode: input.outputBindingMode,
1046
+ });
1047
+ return { preview, settlement };
1048
+ }
1049
+ async function finalizeRedemption(sdk, input) {
1050
+ return buildBondMachineSettlementPlan(sdk, input);
1051
+ }
1052
+ async function prepareClosing(sdk, input) {
1053
+ return buildBondClosing(sdk, input);
1054
+ }
1055
+ async function exportFinalityPayload(sdk, input) {
1056
+ const bondPayload = await buildBondPayload(sdk, input);
1057
+ const evidence = await buildEvidenceBundle(sdk, input);
1058
+ return {
1059
+ payload: bondPayload.payload,
1060
+ bindingMode: input.settlementDescriptorValue?.outputBindingMode ?? "none",
1061
+ trust: bondPayload.trust,
1062
+ trustSummary: {
1063
+ definition: bondPayload.trust.definitionTrust,
1064
+ issuance: bondPayload.trust.issuanceTrust,
1065
+ bindingMode: input.settlementDescriptorValue?.outputBindingMode ?? "none",
1066
+ },
1067
+ evidenceSummary: {
1068
+ definitionHash: evidence.definition.hash,
1069
+ issuanceHash: evidence.issuance.hash,
1070
+ settlementHash: evidence.settlement?.hash ?? null,
1071
+ closingHash: evidence.closing?.hash ?? null,
1072
+ renderedSourceHash: evidence.renderedSourceHash,
1073
+ sourceVerificationMode: evidence.sourceVerificationMode,
1074
+ },
1075
+ };
1076
+ }
1077
+ async function define(sdk, input) {
1078
+ return defineBond(sdk, input);
1079
+ }
1080
+ async function verify(sdk, input) {
1081
+ return verifyBond(sdk, input);
1082
+ }
1083
+ async function load(sdk, input) {
1084
+ return loadBond(sdk, input);
1085
+ }
1086
+ async function issue(sdk, input) {
1087
+ return issueBond(sdk, input);
1088
+ }
1089
+ async function buildSettlement(sdk, input) {
1090
+ return buildBondSettlementPayload(sdk, input);
1091
+ }
1092
+ async function verifySettlement(sdk, input) {
1093
+ return verifyBondSettlementDescriptor(sdk, input);
1094
+ }
1095
+ function resolveRedemptionBindingMode(settlement) {
1096
+ return settlement.descriptor?.outputBindingMode ?? "none";
1097
+ }
1098
+ async function inspectRedemption(sdk, input) {
1099
+ const settlement = await buildBondSettlementPayload(sdk, {
1100
+ definitionPath: input.definitionPath,
1101
+ definitionValue: input.definitionValue,
1102
+ previousIssuancePath: input.previousIssuancePath,
1103
+ previousIssuanceValue: input.previousIssuanceValue,
1104
+ nextIssuancePath: input.nextIssuancePath,
1105
+ nextIssuanceValue: input.nextIssuanceValue,
1106
+ nextStateSimfPath: input.nextStateSimfPath,
1107
+ nextAmountSat: input.nextAmountSat ?? 1900,
1108
+ maxFeeSat: input.maxFeeSat,
1109
+ nextOutputHash: input.nextOutputHash,
1110
+ outputForm: input.outputForm,
1111
+ rawOutput: input.rawOutput,
1112
+ outputBindingMode: input.outputBindingMode,
1113
+ });
1114
+ const mode = resolveRedemptionBindingMode(settlement);
1115
+ if (mode === "descriptor-bound") {
1116
+ const result = await inspectBondDescriptorBoundMachineRollover(sdk, {
1117
+ ...input,
1118
+ nextAmountSat: input.nextAmountSat,
1119
+ maxFeeSat: input.maxFeeSat,
1120
+ nextOutputHash: input.nextOutputHash,
1121
+ });
1122
+ return { mode, settlement, ...result };
1123
+ }
1124
+ if (mode === "script-bound") {
1125
+ const result = await inspectBondScriptBoundMachineRollover(sdk, {
1126
+ ...input,
1127
+ nextAmountSat: input.nextAmountSat,
1128
+ maxFeeSat: input.maxFeeSat,
1129
+ });
1130
+ return { mode, settlement, ...result };
1131
+ }
1132
+ const result = await inspectBondMachineRollover(sdk, input);
1133
+ return { mode, settlement, ...result };
1134
+ }
1135
+ async function executeRedemption(sdk, input) {
1136
+ const settlement = await buildBondSettlementPayload(sdk, {
1137
+ definitionPath: input.definitionPath,
1138
+ definitionValue: input.definitionValue,
1139
+ previousIssuancePath: input.previousIssuancePath,
1140
+ previousIssuanceValue: input.previousIssuanceValue,
1141
+ nextIssuancePath: input.nextIssuancePath,
1142
+ nextIssuanceValue: input.nextIssuanceValue,
1143
+ nextStateSimfPath: input.nextStateSimfPath,
1144
+ nextAmountSat: input.nextAmountSat ?? 1900,
1145
+ maxFeeSat: input.maxFeeSat,
1146
+ nextOutputHash: input.nextOutputHash,
1147
+ outputForm: input.outputForm,
1148
+ rawOutput: input.rawOutput,
1149
+ outputBindingMode: input.outputBindingMode,
1150
+ });
1151
+ const mode = resolveRedemptionBindingMode(settlement);
1152
+ if (mode === "descriptor-bound") {
1153
+ const result = await executeBondDescriptorBoundMachineRollover(sdk, {
1154
+ ...input,
1155
+ nextAmountSat: input.nextAmountSat,
1156
+ maxFeeSat: input.maxFeeSat,
1157
+ nextOutputHash: input.nextOutputHash,
1158
+ });
1159
+ return { mode, settlement, ...result };
1160
+ }
1161
+ if (mode === "script-bound") {
1162
+ const result = await executeBondScriptBoundMachineRollover(sdk, {
1163
+ ...input,
1164
+ nextAmountSat: input.nextAmountSat,
1165
+ maxFeeSat: input.maxFeeSat,
1166
+ });
1167
+ return { mode, settlement, ...result };
1168
+ }
1169
+ const result = await executeBondMachineRollover(sdk, input);
1170
+ return { mode, settlement, ...result };
1171
+ }
1172
+ async function verifyRedemption(sdk, input) {
1173
+ const settlement = await buildBondSettlementPayload(sdk, {
1174
+ definitionPath: input.definitionPath,
1175
+ definitionValue: input.definitionValue,
1176
+ previousIssuancePath: input.previousIssuancePath,
1177
+ previousIssuanceValue: input.previousIssuanceValue,
1178
+ nextIssuancePath: input.nextIssuancePath,
1179
+ nextIssuanceValue: input.nextIssuanceValue,
1180
+ nextStateSimfPath: input.nextStateSimfPath,
1181
+ nextAmountSat: input.nextAmountSat ?? 1900,
1182
+ maxFeeSat: input.maxFeeSat,
1183
+ nextOutputHash: input.nextOutputHash,
1184
+ outputForm: input.outputForm,
1185
+ rawOutput: input.rawOutput,
1186
+ outputBindingMode: input.outputBindingMode,
1187
+ });
1188
+ const mode = resolveRedemptionBindingMode(settlement);
1189
+ if (mode === "descriptor-bound") {
1190
+ const result = await verifyBondDescriptorBoundSettlementMachineArtifact(sdk, {
1191
+ ...input,
1192
+ nextAmountSat: input.nextAmountSat,
1193
+ maxFeeSat: input.maxFeeSat,
1194
+ nextOutputHash: input.nextOutputHash,
1195
+ outputForm: input.outputForm,
1196
+ });
1197
+ return { mode, settlement, ...result };
1198
+ }
1199
+ if (mode === "script-bound") {
1200
+ const result = await verifyBondScriptBoundSettlementMachineArtifact(sdk, {
1201
+ ...input,
1202
+ nextAmountSat: input.nextAmountSat,
1203
+ maxFeeSat: input.maxFeeSat,
1204
+ outputForm: input.outputForm,
1205
+ });
1206
+ return { mode, settlement, ...result };
1207
+ }
1208
+ const result = await verifyBondRedemptionMachineArtifact(sdk, {
1209
+ ...input,
1210
+ outputForm: input.outputForm,
1211
+ });
1212
+ return { mode, settlement, ...result };
1213
+ }
1214
+ async function inspectClosing(sdk, input) {
1215
+ return inspectBondClosing(sdk, input);
1216
+ }
1217
+ async function executeClosing(sdk, input) {
1218
+ return executeBondClosing(sdk, input);
1219
+ }
1220
+ async function verifyClosing(sdk, input) {
1221
+ return verifyBondClosing(sdk, input);
1222
+ }
1223
+ async function exportEvidence(sdk, input) {
1224
+ return buildEvidenceBundle(sdk, input);
1225
+ }
496
1226
  async function compileBondTransition(sdk, input) {
497
1227
  const transitionPayload = await buildBondTransitionPayload(sdk, {
498
1228
  definitionPath: input.definitionPath,
@@ -520,7 +1250,7 @@ async function compileBondTransition(sdk, input) {
520
1250
  id: transitionPayload.next.issuanceId,
521
1251
  ...nextSource,
522
1252
  });
523
- const simfPath = input.simfPath ?? node_path_1.default.resolve(process.cwd(), "docs/definitions/bond-redemption-transition.simf");
1253
+ const simfPath = input.simfPath ?? resolveBondDocsAsset("bond-redemption-transition.simf");
524
1254
  const rawSource = await Promise.resolve().then(() => __importStar(require("node:fs/promises"))).then((fs) => fs.readFile(simfPath, "utf8"));
525
1255
  const previousAnchor = detectPreviousStateAnchor(rawSource);
526
1256
  if (!previousAnchor.sourceVerified) {
@@ -605,6 +1335,10 @@ async function verifyBondRedemptionMachineArtifact(sdk, input) {
605
1335
  nextStateSimfPath: input.nextStateSimfPath,
606
1336
  nextAmountSat: input.nextAmountSat ?? 1900,
607
1337
  maxFeeSat: input.maxFeeSat ?? 100,
1338
+ nextOutputHash: input.nextOutputHash,
1339
+ outputForm: input.outputForm,
1340
+ rawOutput: input.rawOutput,
1341
+ outputBindingMode: input.outputBindingMode,
608
1342
  });
609
1343
  const templateVars = artifact.source.templateVars ?? {};
610
1344
  const committed = {
@@ -619,7 +1353,10 @@ async function verifyBondRedemptionMachineArtifact(sdk, input) {
619
1353
  nextOutstanding32: String(templateVars.NEXT_OUTSTANDING_32 ?? ""),
620
1354
  nextRedeemed32: String(templateVars.NEXT_REDEEMED_32 ?? ""),
621
1355
  nextContractAddressHash256: String(templateVars.NEXT_CONTRACT_ADDRESS_HASH_256 ?? ""),
1356
+ expectedNextOutputHash256: String(templateVars.EXPECTED_NEXT_OUTPUT_HASH_256 ?? ""),
1357
+ expectedNextOutputScriptHash256: String(templateVars.EXPECTED_NEXT_OUTPUT_SCRIPT_HASH_256 ?? ""),
622
1358
  settlementDescriptorHash256: String(templateVars.SETTLEMENT_DESCRIPTOR_HASH ?? ""),
1359
+ expectedOutputDescriptorHash256: String(templateVars.EXPECTED_OUTPUT_DESCRIPTOR_HASH ?? ""),
623
1360
  };
624
1361
  const checks = {
625
1362
  previousStateHashCommitted: committed.previousStateHash === expected.payload.previousStateHash,
@@ -633,7 +1370,14 @@ async function verifyBondRedemptionMachineArtifact(sdk, input) {
633
1370
  && committed.nextOutstanding32 === toUint32Hex(expected.payload.principal.nextOutstanding)
634
1371
  && committed.nextRedeemed32 === toUint32Hex(expected.payload.principal.nextRedeemed),
635
1372
  nextContractAddressCommitted: committed.nextContractAddressHash256 === expectedNextContractAddressHash,
1373
+ nextOutputHashCommitted: !expectedSettlement.expectedOutputDescriptor?.nextOutputHash
1374
+ || committed.expectedNextOutputHash256 === expectedSettlement.expectedOutputDescriptor.nextOutputHash,
1375
+ nextOutputScriptCommitted: !expectedSettlement.expectedOutputDescriptor?.nextOutputScriptHash
1376
+ || committed.expectedNextOutputScriptHash256
1377
+ === expectedSettlement.expectedOutputDescriptor.nextOutputScriptHash,
636
1378
  settlementDescriptorCommitted: committed.settlementDescriptorHash256 === expectedSettlement.hash,
1379
+ expectedOutputDescriptorCommitted: !expectedSettlement.expectedOutputDescriptorHash
1380
+ || committed.expectedOutputDescriptorHash256 === expectedSettlement.expectedOutputDescriptorHash,
637
1381
  };
638
1382
  const allChecks = Object.values(checks).every(Boolean);
639
1383
  return {
@@ -647,6 +1391,16 @@ async function verifyBondRedemptionMachineArtifact(sdk, input) {
647
1391
  },
648
1392
  expectedSettlementDescriptor: expectedSettlement.descriptor,
649
1393
  expectedSettlementDescriptorHash: expectedSettlement.hash,
1394
+ outputBindingMetadata: {
1395
+ requestedMode: expectedSettlement.expectedOutputDescriptor?.requestedOutputBindingMode
1396
+ ?? expectedSettlement.descriptor.outputBindingMode
1397
+ ?? "none",
1398
+ supportedForm: expectedSettlement.expectedOutputBindingSupportedForm,
1399
+ reasonCode: expectedSettlement.expectedOutputBindingReasonCode,
1400
+ autoDerived: expectedSettlement.expectedOutputBindingAutoDerived,
1401
+ fallbackReason: expectedSettlement.expectedOutputBindingFallbackReason,
1402
+ bindingInputs: expectedSettlement.expectedOutputBindingInputs,
1403
+ },
650
1404
  expectedNextContractAddress,
651
1405
  expectedNextContractAddressHash,
652
1406
  committed,
@@ -705,8 +1459,12 @@ async function compileBondRedemptionMachine(sdk, input) {
705
1459
  nextStateSimfPath: input.nextStateSimfPath,
706
1460
  nextAmountSat: input.nextAmountSat ?? 1900,
707
1461
  maxFeeSat: input.maxFeeSat ?? 100,
1462
+ nextOutputHash: input.nextOutputHash,
1463
+ outputForm: input.outputForm,
1464
+ rawOutput: input.rawOutput,
1465
+ outputBindingMode: input.outputBindingMode,
708
1466
  });
709
- const simfPath = input.simfPath ?? node_path_1.default.resolve(process.cwd(), "docs/definitions/bond-redemption-state-machine.simf");
1467
+ const simfPath = input.simfPath ?? resolveBondDocsAsset("bond-redemption-state-machine.simf");
710
1468
  const compiled = await sdk.compileFromFile({
711
1469
  simfPath,
712
1470
  templateVars: {
@@ -724,6 +1482,15 @@ async function compileBondRedemptionMachine(sdk, input) {
724
1482
  NEXT_REDEEMED_32: toUint32Hex(transitionResult.payload.principal.nextRedeemed),
725
1483
  NEXT_CONTRACT_ADDRESS_HASH_256: nextStateContractAddressHash,
726
1484
  SETTLEMENT_DESCRIPTOR_HASH: settlementDescriptor.hash,
1485
+ ...(input.expectedOutputDescriptorHash
1486
+ ? { EXPECTED_OUTPUT_DESCRIPTOR_HASH: input.expectedOutputDescriptorHash }
1487
+ : {}),
1488
+ ...(settlementDescriptor.expectedOutputDescriptor?.nextOutputHash
1489
+ ? { EXPECTED_NEXT_OUTPUT_HASH_256: settlementDescriptor.expectedOutputDescriptor.nextOutputHash }
1490
+ : {}),
1491
+ ...(settlementDescriptor.expectedOutputDescriptor?.nextOutputScriptHash
1492
+ ? { EXPECTED_NEXT_OUTPUT_SCRIPT_HASH_256: settlementDescriptor.expectedOutputDescriptor.nextOutputScriptHash }
1493
+ : {}),
727
1494
  },
728
1495
  definition: {
729
1496
  type: definitionDescriptor.definitionType,
@@ -768,39 +1535,173 @@ async function compileBondRedemptionMachine(sdk, input) {
768
1535
  nextStateContractAddressHash,
769
1536
  settlementDescriptor: settlementDescriptor.descriptor,
770
1537
  settlementDescriptorHash: settlementDescriptor.hash,
1538
+ outputBindingMode: settlementDescriptor.descriptor.outputBindingMode ?? "none",
771
1539
  },
772
1540
  };
773
1541
  }
774
- async function buildBondRedemption(sdk, input) {
775
- const definitionSource = resolveValueOrPath({
776
- pathValue: input.definitionPath,
777
- objectValue: input.definitionValue,
778
- });
779
- const previousSource = resolveValueOrPath({
780
- pathValue: input.previousIssuancePath,
781
- objectValue: input.previousIssuanceValue,
782
- });
783
- const definitionDescriptor = await sdk.loadDefinition({
784
- type: "bond",
785
- id: input.definitionValue?.bondId ?? "BOND-2026-001",
786
- ...definitionSource,
787
- });
788
- const previousDescriptor = await sdk.loadStateDocument({
789
- type: "bond-issuance",
790
- id: input.previousIssuanceValue?.issuanceId ?? "BOND-2026-001-ISSUE-1",
791
- ...previousSource,
1542
+ async function compileBondScriptBoundSettlementMachine(sdk, input) {
1543
+ const settlement = await buildBondSettlementDescriptor(sdk, {
1544
+ definitionPath: input.definitionPath,
1545
+ definitionValue: input.definitionValue,
1546
+ previousIssuancePath: input.previousIssuancePath,
1547
+ previousIssuanceValue: input.previousIssuanceValue,
1548
+ nextIssuancePath: input.nextIssuancePath,
1549
+ nextIssuanceValue: input.nextIssuanceValue,
1550
+ nextStateSimfPath: input.nextStateSimfPath,
1551
+ nextAmountSat: input.nextAmountSat ?? 1900,
1552
+ maxFeeSat: input.maxFeeSat ?? 100,
1553
+ rawOutput: input.rawOutput,
1554
+ outputBindingMode: "script-bound",
792
1555
  });
793
- const definition = (0, bondValidation_1.validateBondDefinition)(JSON.parse(definitionDescriptor.canonicalJson));
794
- const previous = (0, bondValidation_1.validateBondIssuanceState)(JSON.parse(previousDescriptor.canonicalJson));
795
- (0, bondValidation_1.validateBondCrossChecks)(definition, previous);
796
- const next = (0, bondValidation_1.buildRedeemedBondIssuanceState)({
797
- previous,
798
- amount: input.amount,
799
- redeemedAt: input.redeemedAt,
1556
+ const base = await compileBondRedemptionMachine(sdk, {
1557
+ ...input,
1558
+ outputBindingMode: "script-bound",
1559
+ expectedOutputDescriptorHash: settlement.expectedOutputDescriptorHash,
1560
+ simfPath: input.simfPath ?? resolveBondDocsAsset("bond-script-bound-settlement-machine.simf"),
800
1561
  });
801
- const transition = (0, bondValidation_1.validateBondStateTransition)(previous, next);
802
1562
  return {
803
- definition,
1563
+ ...base,
1564
+ expectedOutputDescriptor: settlement.expectedOutputDescriptor,
1565
+ expectedOutputDescriptorHash: settlement.expectedOutputDescriptorHash,
1566
+ outputBindingMode: "script-bound",
1567
+ };
1568
+ }
1569
+ async function verifyBondScriptBoundSettlementMachineArtifact(sdk, input) {
1570
+ const base = await verifyBondRedemptionMachineArtifact(sdk, {
1571
+ ...input,
1572
+ outputBindingMode: "script-bound",
1573
+ });
1574
+ return {
1575
+ ...base,
1576
+ outputBindingTrust: {
1577
+ mode: "script-bound",
1578
+ requestedMode: base.outputBindingMetadata.requestedMode,
1579
+ supportedForm: base.outputBindingMetadata.supportedForm,
1580
+ outputCountRuntimeBound: true,
1581
+ feeIndexRuntimeBound: true,
1582
+ settlementDescriptorCommitted: base.checks.settlementDescriptorCommitted,
1583
+ nextContractAddressCommitted: base.checks.nextContractAddressCommitted,
1584
+ nextOutputHashRuntimeBound: false,
1585
+ nextOutputScriptRuntimeBound: true,
1586
+ amountRuntimeBound: false,
1587
+ reasonCode: base.outputBindingMetadata.reasonCode,
1588
+ autoDerived: base.outputBindingMetadata.autoDerived,
1589
+ fallbackReason: base.outputBindingMetadata.fallbackReason,
1590
+ bindingInputs: base.outputBindingMetadata.bindingInputs,
1591
+ },
1592
+ };
1593
+ }
1594
+ async function compileBondDescriptorBoundSettlementMachine(sdk, input) {
1595
+ const settlement = await buildBondSettlementDescriptor(sdk, {
1596
+ definitionPath: input.definitionPath,
1597
+ definitionValue: input.definitionValue,
1598
+ previousIssuancePath: input.previousIssuancePath,
1599
+ previousIssuanceValue: input.previousIssuanceValue,
1600
+ nextIssuancePath: input.nextIssuancePath,
1601
+ nextIssuanceValue: input.nextIssuanceValue,
1602
+ nextStateSimfPath: input.nextStateSimfPath,
1603
+ nextAmountSat: input.nextAmountSat ?? 1900,
1604
+ maxFeeSat: input.maxFeeSat ?? 100,
1605
+ nextOutputHash: input.nextOutputHash,
1606
+ rawOutput: input.rawOutput,
1607
+ outputBindingMode: "descriptor-bound",
1608
+ });
1609
+ if (settlement.descriptor.outputBindingMode !== "descriptor-bound") {
1610
+ const fallback = await compileBondScriptBoundSettlementMachine(sdk, input);
1611
+ return {
1612
+ ...fallback,
1613
+ requestedOutputBindingMode: "descriptor-bound",
1614
+ outputBindingMode: fallback.outputBindingMode,
1615
+ };
1616
+ }
1617
+ const base = await compileBondRedemptionMachine(sdk, {
1618
+ ...input,
1619
+ nextOutputHash: settlement.expectedOutputDescriptor?.nextOutputHash,
1620
+ outputBindingMode: "descriptor-bound",
1621
+ expectedOutputDescriptorHash: settlement.expectedOutputDescriptorHash,
1622
+ simfPath: input.simfPath ?? resolveBondDocsAsset("bond-descriptor-bound-settlement-machine.simf"),
1623
+ });
1624
+ return {
1625
+ ...base,
1626
+ expectedOutputDescriptor: settlement.expectedOutputDescriptor,
1627
+ expectedOutputDescriptorHash: settlement.expectedOutputDescriptorHash,
1628
+ requestedOutputBindingMode: "descriptor-bound",
1629
+ outputBindingMode: "descriptor-bound",
1630
+ };
1631
+ }
1632
+ async function verifyBondDescriptorBoundSettlementMachineArtifact(sdk, input) {
1633
+ const base = await verifyBondRedemptionMachineArtifact(sdk, {
1634
+ ...input,
1635
+ outputBindingMode: "descriptor-bound",
1636
+ });
1637
+ const mode = base.expectedSettlementDescriptor.outputBindingMode === "descriptor-bound" && base.checks.nextOutputHashCommitted
1638
+ ? "descriptor-bound"
1639
+ : "script-bound";
1640
+ return {
1641
+ ...base,
1642
+ outputBindingTrust: {
1643
+ mode,
1644
+ requestedMode: base.outputBindingMetadata.requestedMode,
1645
+ supportedForm: base.outputBindingMetadata.supportedForm,
1646
+ outputCountRuntimeBound: true,
1647
+ feeIndexRuntimeBound: true,
1648
+ settlementDescriptorCommitted: base.checks.settlementDescriptorCommitted,
1649
+ nextContractAddressCommitted: base.checks.nextContractAddressCommitted,
1650
+ nextOutputHashRuntimeBound: mode === "descriptor-bound",
1651
+ nextOutputScriptRuntimeBound: mode !== "descriptor-bound",
1652
+ amountRuntimeBound: false,
1653
+ reasonCode: base.outputBindingMetadata.reasonCode,
1654
+ autoDerived: base.outputBindingMetadata.autoDerived,
1655
+ fallbackReason: base.outputBindingMetadata.fallbackReason,
1656
+ bindingInputs: base.outputBindingMetadata.bindingInputs,
1657
+ },
1658
+ };
1659
+ }
1660
+ async function compileBondClosingMachine(sdk, input) {
1661
+ const closing = await buildBondClosing(sdk, input);
1662
+ const result = await defineBond(sdk, {
1663
+ definitionValue: closing.definition,
1664
+ issuanceValue: closing.closed,
1665
+ simfPath: input.simfPath ?? resolveBondDocsAsset("bond-issuance-anchor.simf"),
1666
+ artifactPath: input.artifactPath,
1667
+ });
1668
+ return {
1669
+ compiled: result,
1670
+ closing: closing.closing,
1671
+ closingHash: closing.closingHash,
1672
+ closedState: closing.closed,
1673
+ };
1674
+ }
1675
+ async function buildBondRedemption(sdk, input) {
1676
+ const definitionSource = resolveValueOrPath({
1677
+ pathValue: input.definitionPath,
1678
+ objectValue: input.definitionValue,
1679
+ });
1680
+ const previousSource = resolveValueOrPath({
1681
+ pathValue: input.previousIssuancePath,
1682
+ objectValue: input.previousIssuanceValue,
1683
+ });
1684
+ const definitionDescriptor = await sdk.loadDefinition({
1685
+ type: "bond",
1686
+ id: input.definitionValue?.bondId ?? "BOND-2026-001",
1687
+ ...definitionSource,
1688
+ });
1689
+ const previousDescriptor = await sdk.loadStateDocument({
1690
+ type: "bond-issuance",
1691
+ id: input.previousIssuanceValue?.issuanceId ?? "BOND-2026-001-ISSUE-1",
1692
+ ...previousSource,
1693
+ });
1694
+ const definition = (0, bondValidation_1.validateBondDefinition)(JSON.parse(definitionDescriptor.canonicalJson));
1695
+ const previous = (0, bondValidation_1.validateBondIssuanceState)(JSON.parse(previousDescriptor.canonicalJson));
1696
+ (0, bondValidation_1.validateBondCrossChecks)(definition, previous);
1697
+ const next = (0, bondValidation_1.buildRedeemedBondIssuanceState)({
1698
+ previous,
1699
+ amount: input.amount,
1700
+ redeemedAt: input.redeemedAt,
1701
+ });
1702
+ const transition = (0, bondValidation_1.validateBondStateTransition)(previous, next);
1703
+ return {
1704
+ definition,
804
1705
  previous,
805
1706
  next,
806
1707
  previousHash: previousDescriptor.hash,
@@ -931,6 +1832,102 @@ async function buildBondMachineRolloverPlan(sdk, input) {
931
1832
  transitionPayload: machineCompiled.payload,
932
1833
  };
933
1834
  }
1835
+ async function buildBondScriptBoundMachineRolloverPlan(sdk, input) {
1836
+ const currentArtifact = input.currentArtifact
1837
+ ?? (input.currentArtifactPath ? (await sdk.loadArtifact(input.currentArtifactPath)).artifact : undefined);
1838
+ if (!currentArtifact) {
1839
+ throw new Error("currentArtifactPath or currentArtifact is required");
1840
+ }
1841
+ const currentVerification = await verifyBond(sdk, {
1842
+ artifact: currentArtifact,
1843
+ definitionPath: input.definitionPath,
1844
+ definitionValue: input.definitionValue,
1845
+ issuancePath: input.previousIssuancePath,
1846
+ issuanceValue: input.previousIssuanceValue,
1847
+ });
1848
+ const machineCompiled = await compileBondScriptBoundSettlementMachine(sdk, {
1849
+ definitionPath: input.definitionPath,
1850
+ definitionValue: input.definitionValue,
1851
+ previousIssuancePath: input.previousIssuancePath,
1852
+ previousIssuanceValue: input.previousIssuanceValue,
1853
+ nextIssuancePath: input.nextIssuancePath,
1854
+ nextIssuanceValue: input.nextIssuanceValue,
1855
+ nextStateSimfPath: input.nextStateSimfPath,
1856
+ nextAmountSat: input.nextAmountSat,
1857
+ maxFeeSat: input.maxFeeSat,
1858
+ simfPath: input.machineSimfPath,
1859
+ artifactPath: input.machineArtifactPath,
1860
+ });
1861
+ const machineVerification = await verifyBondScriptBoundSettlementMachineArtifact(sdk, {
1862
+ artifact: machineCompiled.compiled.artifact,
1863
+ definitionPath: input.definitionPath,
1864
+ definitionValue: input.definitionValue,
1865
+ previousIssuancePath: input.previousIssuancePath,
1866
+ previousIssuanceValue: input.previousIssuanceValue,
1867
+ nextIssuancePath: input.nextIssuancePath,
1868
+ nextIssuanceValue: input.nextIssuanceValue,
1869
+ nextStateSimfPath: input.nextStateSimfPath,
1870
+ nextAmountSat: input.nextAmountSat,
1871
+ maxFeeSat: input.maxFeeSat,
1872
+ });
1873
+ return {
1874
+ currentArtifact,
1875
+ currentVerification,
1876
+ machineCompiled,
1877
+ machineVerification,
1878
+ nextContractAddress: machineCompiled.compiled.deployment().contractAddress,
1879
+ transitionPayload: machineCompiled.payload,
1880
+ };
1881
+ }
1882
+ async function buildBondDescriptorBoundMachineRolloverPlan(sdk, input) {
1883
+ const currentArtifact = input.currentArtifact
1884
+ ?? (input.currentArtifactPath ? (await sdk.loadArtifact(input.currentArtifactPath)).artifact : undefined);
1885
+ if (!currentArtifact) {
1886
+ throw new Error("currentArtifactPath or currentArtifact is required");
1887
+ }
1888
+ const currentVerification = await verifyBond(sdk, {
1889
+ artifact: currentArtifact,
1890
+ definitionPath: input.definitionPath,
1891
+ definitionValue: input.definitionValue,
1892
+ issuancePath: input.previousIssuancePath,
1893
+ issuanceValue: input.previousIssuanceValue,
1894
+ });
1895
+ const machineCompiled = await compileBondDescriptorBoundSettlementMachine(sdk, {
1896
+ definitionPath: input.definitionPath,
1897
+ definitionValue: input.definitionValue,
1898
+ previousIssuancePath: input.previousIssuancePath,
1899
+ previousIssuanceValue: input.previousIssuanceValue,
1900
+ nextIssuancePath: input.nextIssuancePath,
1901
+ nextIssuanceValue: input.nextIssuanceValue,
1902
+ nextStateSimfPath: input.nextStateSimfPath,
1903
+ nextAmountSat: input.nextAmountSat,
1904
+ maxFeeSat: input.maxFeeSat,
1905
+ nextOutputHash: input.nextOutputHash,
1906
+ simfPath: input.machineSimfPath,
1907
+ artifactPath: input.machineArtifactPath,
1908
+ });
1909
+ const machineVerification = await verifyBondDescriptorBoundSettlementMachineArtifact(sdk, {
1910
+ artifact: machineCompiled.compiled.artifact,
1911
+ definitionPath: input.definitionPath,
1912
+ definitionValue: input.definitionValue,
1913
+ previousIssuancePath: input.previousIssuancePath,
1914
+ previousIssuanceValue: input.previousIssuanceValue,
1915
+ nextIssuancePath: input.nextIssuancePath,
1916
+ nextIssuanceValue: input.nextIssuanceValue,
1917
+ nextStateSimfPath: input.nextStateSimfPath,
1918
+ nextAmountSat: input.nextAmountSat,
1919
+ maxFeeSat: input.maxFeeSat,
1920
+ nextOutputHash: input.nextOutputHash,
1921
+ });
1922
+ return {
1923
+ currentArtifact,
1924
+ currentVerification,
1925
+ machineCompiled,
1926
+ machineVerification,
1927
+ nextContractAddress: machineCompiled.compiled.deployment().contractAddress,
1928
+ transitionPayload: machineCompiled.payload,
1929
+ };
1930
+ }
934
1931
  async function buildBondMachineSettlementPlan(sdk, input) {
935
1932
  const currentMachineArtifact = input.currentMachineArtifact
936
1933
  ?? (input.currentMachineArtifactPath ? (await sdk.loadArtifact(input.currentMachineArtifactPath)).artifact : undefined);
@@ -965,6 +1962,79 @@ async function buildBondMachineSettlementPlan(sdk, input) {
965
1962
  nextContractAddressMatchesMachineCommitment: nextCompiled.deployment().contractAddress === machineVerification.expectedNextContractAddress,
966
1963
  };
967
1964
  }
1965
+ async function buildBondScriptBoundMachineSettlementPlan(sdk, input) {
1966
+ const currentMachineArtifact = input.currentMachineArtifact
1967
+ ?? (input.currentMachineArtifactPath ? (await sdk.loadArtifact(input.currentMachineArtifactPath)).artifact : undefined);
1968
+ if (!currentMachineArtifact) {
1969
+ throw new Error("currentMachineArtifactPath or currentMachineArtifact is required");
1970
+ }
1971
+ const machineVerification = await verifyBondScriptBoundSettlementMachineArtifact(sdk, {
1972
+ artifact: currentMachineArtifact,
1973
+ definitionPath: input.definitionPath,
1974
+ definitionValue: input.definitionValue,
1975
+ previousIssuancePath: input.previousIssuancePath,
1976
+ previousIssuanceValue: input.previousIssuanceValue,
1977
+ nextIssuancePath: input.nextIssuancePath,
1978
+ nextIssuanceValue: input.nextIssuanceValue,
1979
+ nextStateSimfPath: input.nextSimfPath,
1980
+ nextAmountSat: input.nextAmountSat,
1981
+ maxFeeSat: input.maxFeeSat,
1982
+ });
1983
+ const definitionValue = (0, bondValidation_1.validateBondDefinition)(JSON.parse(machineVerification.definition.definition.canonicalJson));
1984
+ const nextStateValue = (0, bondValidation_1.validateBondIssuanceState)(JSON.parse(machineVerification.issuance.state.canonicalJson));
1985
+ const nextCompiled = await defineBond(sdk, {
1986
+ definitionPath: input.definitionPath,
1987
+ definitionValue,
1988
+ issuanceValue: nextStateValue,
1989
+ simfPath: input.nextSimfPath,
1990
+ artifactPath: input.nextArtifactPath,
1991
+ });
1992
+ return {
1993
+ currentMachineArtifact,
1994
+ machineVerification,
1995
+ nextCompiled,
1996
+ nextContractAddress: nextCompiled.deployment().contractAddress,
1997
+ transitionPayload: machineVerification.expectedPayload,
1998
+ nextContractAddressMatchesMachineCommitment: nextCompiled.deployment().contractAddress === machineVerification.expectedNextContractAddress,
1999
+ };
2000
+ }
2001
+ async function buildBondDescriptorBoundMachineSettlementPlan(sdk, input) {
2002
+ const currentMachineArtifact = input.currentMachineArtifact
2003
+ ?? (input.currentMachineArtifactPath ? (await sdk.loadArtifact(input.currentMachineArtifactPath)).artifact : undefined);
2004
+ if (!currentMachineArtifact) {
2005
+ throw new Error("currentMachineArtifactPath or currentMachineArtifact is required");
2006
+ }
2007
+ const machineVerification = await verifyBondDescriptorBoundSettlementMachineArtifact(sdk, {
2008
+ artifact: currentMachineArtifact,
2009
+ definitionPath: input.definitionPath,
2010
+ definitionValue: input.definitionValue,
2011
+ previousIssuancePath: input.previousIssuancePath,
2012
+ previousIssuanceValue: input.previousIssuanceValue,
2013
+ nextIssuancePath: input.nextIssuancePath,
2014
+ nextIssuanceValue: input.nextIssuanceValue,
2015
+ nextStateSimfPath: input.nextSimfPath,
2016
+ nextAmountSat: input.nextAmountSat,
2017
+ maxFeeSat: input.maxFeeSat,
2018
+ nextOutputHash: input.nextOutputHash,
2019
+ });
2020
+ const definitionValue = (0, bondValidation_1.validateBondDefinition)(JSON.parse(machineVerification.definition.definition.canonicalJson));
2021
+ const nextStateValue = (0, bondValidation_1.validateBondIssuanceState)(JSON.parse(machineVerification.issuance.state.canonicalJson));
2022
+ const nextCompiled = await defineBond(sdk, {
2023
+ definitionPath: input.definitionPath,
2024
+ definitionValue,
2025
+ issuanceValue: nextStateValue,
2026
+ simfPath: input.nextSimfPath,
2027
+ artifactPath: input.nextArtifactPath,
2028
+ });
2029
+ return {
2030
+ currentMachineArtifact,
2031
+ machineVerification,
2032
+ nextCompiled,
2033
+ nextContractAddress: nextCompiled.deployment().contractAddress,
2034
+ transitionPayload: machineVerification.expectedPayload,
2035
+ nextContractAddressMatchesMachineCommitment: nextCompiled.deployment().contractAddress === machineVerification.expectedNextContractAddress,
2036
+ };
2037
+ }
968
2038
  async function inspectBondStateRollover(sdk, input) {
969
2039
  const plan = await buildBondRolloverPlan(sdk, input);
970
2040
  const contract = sdk.fromArtifact(plan.currentArtifact);
@@ -989,6 +2059,30 @@ async function inspectBondMachineRollover(sdk, input) {
989
2059
  });
990
2060
  return { plan, inspect };
991
2061
  }
2062
+ async function inspectBondScriptBoundMachineRollover(sdk, input) {
2063
+ const plan = await buildBondScriptBoundMachineRolloverPlan(sdk, input);
2064
+ const contract = sdk.fromArtifact(plan.currentArtifact);
2065
+ const inspect = await contract.inspectCall({
2066
+ wallet: input.wallet,
2067
+ toAddress: plan.nextContractAddress,
2068
+ signer: input.signer,
2069
+ feeSat: input.feeSat,
2070
+ utxoPolicy: input.utxoPolicy,
2071
+ });
2072
+ return { plan, inspect };
2073
+ }
2074
+ async function inspectBondDescriptorBoundMachineRollover(sdk, input) {
2075
+ const plan = await buildBondDescriptorBoundMachineRolloverPlan(sdk, input);
2076
+ const contract = sdk.fromArtifact(plan.currentArtifact);
2077
+ const inspect = await contract.inspectCall({
2078
+ wallet: input.wallet,
2079
+ toAddress: plan.nextContractAddress,
2080
+ signer: input.signer,
2081
+ feeSat: input.feeSat,
2082
+ utxoPolicy: input.utxoPolicy,
2083
+ });
2084
+ return { plan, inspect };
2085
+ }
992
2086
  async function inspectBondMachineSettlement(sdk, input) {
993
2087
  const plan = await buildBondMachineSettlementPlan(sdk, input);
994
2088
  const contract = sdk.fromArtifact(plan.currentMachineArtifact);
@@ -1001,6 +2095,76 @@ async function inspectBondMachineSettlement(sdk, input) {
1001
2095
  });
1002
2096
  return { plan, inspect };
1003
2097
  }
2098
+ async function inspectBondScriptBoundMachineSettlement(sdk, input) {
2099
+ const plan = await buildBondScriptBoundMachineSettlementPlan(sdk, input);
2100
+ const contract = sdk.fromArtifact(plan.currentMachineArtifact);
2101
+ const inspect = await contract.inspectCall({
2102
+ wallet: input.wallet,
2103
+ toAddress: plan.nextContractAddress,
2104
+ signer: input.signer,
2105
+ feeSat: input.feeSat,
2106
+ utxoPolicy: input.utxoPolicy,
2107
+ });
2108
+ return { plan, inspect };
2109
+ }
2110
+ async function inspectBondDescriptorBoundMachineSettlement(sdk, input) {
2111
+ const plan = await buildBondDescriptorBoundMachineSettlementPlan(sdk, input);
2112
+ const contract = sdk.fromArtifact(plan.currentMachineArtifact);
2113
+ const inspect = await contract.inspectCall({
2114
+ wallet: input.wallet,
2115
+ toAddress: plan.nextContractAddress,
2116
+ signer: input.signer,
2117
+ feeSat: input.feeSat,
2118
+ utxoPolicy: input.utxoPolicy,
2119
+ });
2120
+ return { plan, inspect };
2121
+ }
2122
+ async function buildBondClosingPlan(sdk, input) {
2123
+ const currentArtifact = input.currentArtifact
2124
+ ?? (input.currentArtifactPath ? (await sdk.loadArtifact(input.currentArtifactPath)).artifact : undefined);
2125
+ if (!currentArtifact) {
2126
+ throw new Error("currentArtifactPath or currentArtifact is required");
2127
+ }
2128
+ const currentVerification = await verifyBond(sdk, {
2129
+ artifact: currentArtifact,
2130
+ definitionPath: input.definitionPath,
2131
+ definitionValue: input.definitionValue,
2132
+ issuancePath: input.redeemedIssuancePath,
2133
+ issuanceValue: input.redeemedIssuanceValue,
2134
+ });
2135
+ const closingCompiled = await compileBondClosingMachine(sdk, {
2136
+ definitionPath: input.definitionPath,
2137
+ definitionValue: input.definitionValue,
2138
+ redeemedIssuancePath: input.redeemedIssuancePath,
2139
+ redeemedIssuanceValue: input.redeemedIssuanceValue,
2140
+ settlementDescriptorPath: input.settlementDescriptorPath,
2141
+ settlementDescriptorValue: input.settlementDescriptorValue,
2142
+ closedAt: input.closedAt,
2143
+ closingReason: input.closingReason,
2144
+ simfPath: input.closedIssuanceSimfPath,
2145
+ artifactPath: input.closingArtifactPath,
2146
+ });
2147
+ const closingVerification = await verifyBondClosing(sdk, {
2148
+ definitionPath: input.definitionPath,
2149
+ definitionValue: input.definitionValue,
2150
+ redeemedIssuancePath: input.redeemedIssuancePath,
2151
+ redeemedIssuanceValue: input.redeemedIssuanceValue,
2152
+ closedIssuanceValue: closingCompiled.closedState,
2153
+ settlementDescriptorPath: input.settlementDescriptorPath,
2154
+ settlementDescriptorValue: input.settlementDescriptorValue,
2155
+ closingDescriptorValue: closingCompiled.closing,
2156
+ });
2157
+ return {
2158
+ currentArtifact,
2159
+ currentVerification,
2160
+ closingCompiled,
2161
+ closingVerification,
2162
+ nextContractAddress: closingCompiled.compiled.deployment().contractAddress,
2163
+ closingDescriptor: closingCompiled.closing,
2164
+ closingHash: closingCompiled.closingHash,
2165
+ closedState: closingCompiled.closedState,
2166
+ };
2167
+ }
1004
2168
  async function executeBondStateRollover(sdk, input) {
1005
2169
  const plan = await buildBondRolloverPlan(sdk, input);
1006
2170
  const contract = sdk.fromArtifact(plan.currentArtifact);
@@ -1027,6 +2191,32 @@ async function executeBondMachineRollover(sdk, input) {
1027
2191
  });
1028
2192
  return { plan, execution };
1029
2193
  }
2194
+ async function executeBondScriptBoundMachineRollover(sdk, input) {
2195
+ const plan = await buildBondScriptBoundMachineRolloverPlan(sdk, input);
2196
+ const contract = sdk.fromArtifact(plan.currentArtifact);
2197
+ const execution = await contract.execute({
2198
+ wallet: input.wallet,
2199
+ toAddress: plan.nextContractAddress,
2200
+ signer: input.signer,
2201
+ feeSat: input.feeSat,
2202
+ utxoPolicy: input.utxoPolicy,
2203
+ broadcast: input.broadcast,
2204
+ });
2205
+ return { plan, execution };
2206
+ }
2207
+ async function executeBondDescriptorBoundMachineRollover(sdk, input) {
2208
+ const plan = await buildBondDescriptorBoundMachineRolloverPlan(sdk, input);
2209
+ const contract = sdk.fromArtifact(plan.currentArtifact);
2210
+ const execution = await contract.execute({
2211
+ wallet: input.wallet,
2212
+ toAddress: plan.nextContractAddress,
2213
+ signer: input.signer,
2214
+ feeSat: input.feeSat,
2215
+ utxoPolicy: input.utxoPolicy,
2216
+ broadcast: input.broadcast,
2217
+ });
2218
+ return { plan, execution };
2219
+ }
1030
2220
  async function executeBondMachineSettlement(sdk, input) {
1031
2221
  const plan = await buildBondMachineSettlementPlan(sdk, input);
1032
2222
  const contract = sdk.fromArtifact(plan.currentMachineArtifact);
@@ -1040,3 +2230,54 @@ async function executeBondMachineSettlement(sdk, input) {
1040
2230
  });
1041
2231
  return { plan, execution };
1042
2232
  }
2233
+ async function executeBondScriptBoundMachineSettlement(sdk, input) {
2234
+ const plan = await buildBondScriptBoundMachineSettlementPlan(sdk, input);
2235
+ const contract = sdk.fromArtifact(plan.currentMachineArtifact);
2236
+ const execution = await contract.execute({
2237
+ wallet: input.wallet,
2238
+ toAddress: plan.nextContractAddress,
2239
+ signer: input.signer,
2240
+ feeSat: input.feeSat,
2241
+ utxoPolicy: input.utxoPolicy,
2242
+ broadcast: input.broadcast,
2243
+ });
2244
+ return { plan, execution };
2245
+ }
2246
+ async function executeBondDescriptorBoundMachineSettlement(sdk, input) {
2247
+ const plan = await buildBondDescriptorBoundMachineSettlementPlan(sdk, input);
2248
+ const contract = sdk.fromArtifact(plan.currentMachineArtifact);
2249
+ const execution = await contract.execute({
2250
+ wallet: input.wallet,
2251
+ toAddress: plan.nextContractAddress,
2252
+ signer: input.signer,
2253
+ feeSat: input.feeSat,
2254
+ utxoPolicy: input.utxoPolicy,
2255
+ broadcast: input.broadcast,
2256
+ });
2257
+ return { plan, execution };
2258
+ }
2259
+ async function inspectBondClosing(sdk, input) {
2260
+ const plan = await buildBondClosingPlan(sdk, input);
2261
+ const contract = sdk.fromArtifact(plan.currentArtifact);
2262
+ const inspect = await contract.inspectCall({
2263
+ wallet: input.wallet,
2264
+ toAddress: plan.nextContractAddress,
2265
+ signer: input.signer,
2266
+ feeSat: input.feeSat,
2267
+ utxoPolicy: input.utxoPolicy,
2268
+ });
2269
+ return { plan, inspect };
2270
+ }
2271
+ async function executeBondClosing(sdk, input) {
2272
+ const plan = await buildBondClosingPlan(sdk, input);
2273
+ const contract = sdk.fromArtifact(plan.currentArtifact);
2274
+ const execution = await contract.execute({
2275
+ wallet: input.wallet,
2276
+ toAddress: plan.nextContractAddress,
2277
+ signer: input.signer,
2278
+ feeSat: input.feeSat,
2279
+ utxoPolicy: input.utxoPolicy,
2280
+ broadcast: input.broadcast,
2281
+ });
2282
+ return { plan, execution };
2283
+ }