@hazbase/simplicity 0.0.5 → 0.2.0
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 +140 -1038
- package/dist/cli.js +3341 -269
- package/dist/client/SimplicityClient.d.ts +91 -290
- package/dist/client/SimplicityClient.js +93 -23
- package/dist/core/executor.js +67 -92
- package/dist/core/lineage.d.ts +18 -0
- package/dist/core/lineage.js +30 -0
- package/dist/core/outputBinding.d.ts +61 -0
- package/dist/core/outputBinding.js +552 -0
- package/dist/core/reporting.d.ts +22 -0
- package/dist/core/reporting.js +40 -0
- package/dist/core/schnorr.d.ts +5 -0
- package/dist/core/schnorr.js +46 -0
- package/dist/core/types.d.ts +799 -1
- package/dist/docs/definitions/bond-anchor.simf +19 -0
- package/dist/docs/definitions/bond-definition.json +10 -0
- package/dist/docs/definitions/bond-descriptor-bound-settlement-machine.simf +144 -0
- package/dist/docs/definitions/bond-issuance-anchor.simf +26 -0
- package/dist/docs/definitions/bond-issuance-state-partial-redemption.json +18 -0
- package/dist/docs/definitions/bond-issuance-state-redeemed.json +18 -0
- package/dist/docs/definitions/bond-issuance-state.json +12 -0
- package/dist/docs/definitions/bond-redemption-state-machine.simf +118 -0
- package/dist/docs/definitions/bond-redemption-transition.simf +41 -0
- package/dist/docs/definitions/bond-script-bound-settlement-machine.simf +142 -0
- package/dist/docs/definitions/fund-capital-call-open.simf +82 -0
- package/dist/docs/definitions/fund-capital-call-refund-only.simf +67 -0
- package/dist/docs/definitions/fund-capital-call-state.json +11 -0
- package/dist/docs/definitions/fund-definition.json +8 -0
- package/dist/docs/definitions/fund-distribution-claim.simf +57 -0
- package/dist/docs/definitions/receivable-definition.json +9 -0
- package/dist/docs/definitions/receivable-funding-claim.json +13 -0
- package/dist/docs/definitions/receivable-funding-claim.simf +58 -0
- package/dist/docs/definitions/receivable-repayment-claim.json +13 -0
- package/dist/docs/definitions/receivable-repayment-claim.simf +59 -0
- package/dist/docs/definitions/receivable-state-funded.json +20 -0
- package/dist/docs/definitions/receivable-state-originated.json +19 -0
- package/dist/docs/definitions/receivable-state-repaid.json +20 -0
- package/dist/docs/definitions/recursive-delay-direct-next.simf +60 -0
- package/dist/docs/definitions/recursive-delay-optional.simf +88 -0
- package/dist/docs/definitions/recursive-delay-required.simf +72 -0
- package/dist/docs/definitions/recursive-delay.simf +83 -0
- package/dist/docs/definitions/recursive-policy-transfer-machine.simf +65 -0
- package/dist/domain/bond.d.ts +8649 -720
- package/dist/domain/bond.js +1398 -8
- package/dist/domain/bondSettlementValidation.d.ts +2 -0
- package/dist/domain/bondSettlementValidation.js +28 -0
- package/dist/domain/bondValidation.d.ts +37 -1
- package/dist/domain/bondValidation.js +137 -11
- package/dist/domain/fund.d.ts +2452 -0
- package/dist/domain/fund.js +1756 -0
- package/dist/domain/fundValidation.d.ts +152 -0
- package/dist/domain/fundValidation.js +767 -0
- package/dist/domain/policies.d.ts +1064 -0
- package/dist/domain/policies.js +1625 -0
- package/dist/domain/receivable.d.ts +824 -0
- package/dist/domain/receivable.js +1375 -0
- package/dist/domain/receivableValidation.d.ts +147 -0
- package/dist/domain/receivableValidation.js +831 -0
- package/dist/index.d.ts +8 -2
- package/dist/index.js +137 -21
- package/package.json +20 -2
package/dist/domain/bond.js
CHANGED
|
@@ -40,27 +40,77 @@ exports.defineBond = defineBond;
|
|
|
40
40
|
exports.verifyBond = verifyBond;
|
|
41
41
|
exports.loadBond = loadBond;
|
|
42
42
|
exports.buildBondPayload = buildBondPayload;
|
|
43
|
+
exports.verifyIssuanceHistory = verifyIssuanceHistory;
|
|
44
|
+
exports.summarizeExpectedOutputDescriptor = summarizeExpectedOutputDescriptor;
|
|
45
|
+
exports.validateExpectedOutputDescriptor = validateExpectedOutputDescriptor;
|
|
46
|
+
exports.buildExpectedOutputDescriptor = buildExpectedOutputDescriptor;
|
|
47
|
+
exports.verifyExpectedOutputDescriptor = verifyExpectedOutputDescriptor;
|
|
43
48
|
exports.redeemBond = redeemBond;
|
|
44
49
|
exports.buildBondTransitionPayload = buildBondTransitionPayload;
|
|
45
50
|
exports.buildBondSettlementDescriptor = buildBondSettlementDescriptor;
|
|
46
51
|
exports.verifyBondSettlementDescriptor = verifyBondSettlementDescriptor;
|
|
47
52
|
exports.buildBondSettlementPayload = buildBondSettlementPayload;
|
|
53
|
+
exports.buildBondClosing = buildBondClosing;
|
|
54
|
+
exports.verifyBondClosing = verifyBondClosing;
|
|
55
|
+
exports.buildEvidenceBundle = buildEvidenceBundle;
|
|
56
|
+
exports.verifyEvidenceBundle = verifyEvidenceBundle;
|
|
57
|
+
exports.issueBond = issueBond;
|
|
58
|
+
exports.prepareRedemption = prepareRedemption;
|
|
59
|
+
exports.finalizeRedemption = finalizeRedemption;
|
|
60
|
+
exports.prepareClosing = prepareClosing;
|
|
61
|
+
exports.exportFinalityPayload = exportFinalityPayload;
|
|
62
|
+
exports.define = define;
|
|
63
|
+
exports.verify = verify;
|
|
64
|
+
exports.load = load;
|
|
65
|
+
exports.issue = issue;
|
|
66
|
+
exports.buildSettlement = buildSettlement;
|
|
67
|
+
exports.verifySettlement = verifySettlement;
|
|
68
|
+
exports.inspectRedemption = inspectRedemption;
|
|
69
|
+
exports.executeRedemption = executeRedemption;
|
|
70
|
+
exports.verifyRedemption = verifyRedemption;
|
|
71
|
+
exports.inspectClosing = inspectClosing;
|
|
72
|
+
exports.executeClosing = executeClosing;
|
|
73
|
+
exports.verifyClosing = verifyClosing;
|
|
74
|
+
exports.exportEvidence = exportEvidence;
|
|
48
75
|
exports.compileBondTransition = compileBondTransition;
|
|
49
76
|
exports.verifyBondRedemptionMachineArtifact = verifyBondRedemptionMachineArtifact;
|
|
50
77
|
exports.compileBondRedemptionMachine = compileBondRedemptionMachine;
|
|
78
|
+
exports.compileBondScriptBoundSettlementMachine = compileBondScriptBoundSettlementMachine;
|
|
79
|
+
exports.verifyBondScriptBoundSettlementMachineArtifact = verifyBondScriptBoundSettlementMachineArtifact;
|
|
80
|
+
exports.compileBondDescriptorBoundSettlementMachine = compileBondDescriptorBoundSettlementMachine;
|
|
81
|
+
exports.verifyBondDescriptorBoundSettlementMachineArtifact = verifyBondDescriptorBoundSettlementMachineArtifact;
|
|
82
|
+
exports.compileBondClosingMachine = compileBondClosingMachine;
|
|
51
83
|
exports.buildBondRedemption = buildBondRedemption;
|
|
52
84
|
exports.verifyBondTransition = verifyBondTransition;
|
|
53
85
|
exports.buildBondRolloverPlan = buildBondRolloverPlan;
|
|
54
86
|
exports.buildBondMachineRolloverPlan = buildBondMachineRolloverPlan;
|
|
87
|
+
exports.buildBondScriptBoundMachineRolloverPlan = buildBondScriptBoundMachineRolloverPlan;
|
|
88
|
+
exports.buildBondDescriptorBoundMachineRolloverPlan = buildBondDescriptorBoundMachineRolloverPlan;
|
|
55
89
|
exports.buildBondMachineSettlementPlan = buildBondMachineSettlementPlan;
|
|
90
|
+
exports.buildBondScriptBoundMachineSettlementPlan = buildBondScriptBoundMachineSettlementPlan;
|
|
91
|
+
exports.buildBondDescriptorBoundMachineSettlementPlan = buildBondDescriptorBoundMachineSettlementPlan;
|
|
56
92
|
exports.inspectBondStateRollover = inspectBondStateRollover;
|
|
57
93
|
exports.inspectBondMachineRollover = inspectBondMachineRollover;
|
|
94
|
+
exports.inspectBondScriptBoundMachineRollover = inspectBondScriptBoundMachineRollover;
|
|
95
|
+
exports.inspectBondDescriptorBoundMachineRollover = inspectBondDescriptorBoundMachineRollover;
|
|
58
96
|
exports.inspectBondMachineSettlement = inspectBondMachineSettlement;
|
|
97
|
+
exports.inspectBondScriptBoundMachineSettlement = inspectBondScriptBoundMachineSettlement;
|
|
98
|
+
exports.inspectBondDescriptorBoundMachineSettlement = inspectBondDescriptorBoundMachineSettlement;
|
|
99
|
+
exports.buildBondClosingPlan = buildBondClosingPlan;
|
|
59
100
|
exports.executeBondStateRollover = executeBondStateRollover;
|
|
60
101
|
exports.executeBondMachineRollover = executeBondMachineRollover;
|
|
102
|
+
exports.executeBondScriptBoundMachineRollover = executeBondScriptBoundMachineRollover;
|
|
103
|
+
exports.executeBondDescriptorBoundMachineRollover = executeBondDescriptorBoundMachineRollover;
|
|
61
104
|
exports.executeBondMachineSettlement = executeBondMachineSettlement;
|
|
105
|
+
exports.executeBondScriptBoundMachineSettlement = executeBondScriptBoundMachineSettlement;
|
|
106
|
+
exports.executeBondDescriptorBoundMachineSettlement = executeBondDescriptorBoundMachineSettlement;
|
|
107
|
+
exports.inspectBondClosing = inspectBondClosing;
|
|
108
|
+
exports.executeBondClosing = executeBondClosing;
|
|
109
|
+
const node_fs_1 = require("node:fs");
|
|
62
110
|
const node_path_1 = __importDefault(require("node:path"));
|
|
111
|
+
const reporting_1 = require("../core/reporting");
|
|
63
112
|
const summary_1 = require("../core/summary");
|
|
113
|
+
const outputBinding_1 = require("../core/outputBinding");
|
|
64
114
|
const bondSettlementValidation_1 = require("./bondSettlementValidation");
|
|
65
115
|
const bondValidation_1 = require("./bondValidation");
|
|
66
116
|
function resolveValueOrPath(options) {
|
|
@@ -70,6 +120,106 @@ function resolveValueOrPath(options) {
|
|
|
70
120
|
return { value: options.objectValue };
|
|
71
121
|
return {};
|
|
72
122
|
}
|
|
123
|
+
function resolveBondDocsAsset(filename) {
|
|
124
|
+
const cwdCandidate = node_path_1.default.resolve(process.cwd(), "docs/definitions", filename);
|
|
125
|
+
if ((0, node_fs_1.existsSync)(cwdCandidate)) {
|
|
126
|
+
return cwdCandidate;
|
|
127
|
+
}
|
|
128
|
+
// In published packages we copy bond example contracts into dist/docs/definitions.
|
|
129
|
+
const bundledCandidate = node_path_1.default.resolve(__dirname, "../docs/definitions", filename);
|
|
130
|
+
if ((0, node_fs_1.existsSync)(bundledCandidate)) {
|
|
131
|
+
return bundledCandidate;
|
|
132
|
+
}
|
|
133
|
+
return cwdCandidate;
|
|
134
|
+
}
|
|
135
|
+
async function loadIssuanceHistoryDocuments(sdk, input) {
|
|
136
|
+
const results = [];
|
|
137
|
+
for (const issuancePath of input.issuanceHistoryPaths ?? []) {
|
|
138
|
+
const state = await sdk.loadStateDocument({
|
|
139
|
+
type: "bond-issuance",
|
|
140
|
+
id: "BOND-ISSUANCE-HISTORY",
|
|
141
|
+
jsonPath: issuancePath,
|
|
142
|
+
});
|
|
143
|
+
const value = (0, bondValidation_1.validateBondIssuanceState)(JSON.parse(state.canonicalJson));
|
|
144
|
+
results.push({
|
|
145
|
+
state,
|
|
146
|
+
value,
|
|
147
|
+
summary: (0, bondValidation_1.summarizeBondIssuanceState)(value),
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
for (const issuanceValue of input.issuanceHistoryValues ?? []) {
|
|
151
|
+
const value = (0, bondValidation_1.validateBondIssuanceState)(issuanceValue);
|
|
152
|
+
const state = await sdk.loadStateDocument({
|
|
153
|
+
type: "bond-issuance",
|
|
154
|
+
id: value.issuanceId,
|
|
155
|
+
value,
|
|
156
|
+
});
|
|
157
|
+
results.push({
|
|
158
|
+
state,
|
|
159
|
+
value,
|
|
160
|
+
summary: (0, bondValidation_1.summarizeBondIssuanceState)(value),
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
return results;
|
|
164
|
+
}
|
|
165
|
+
function buildBondIssuanceLineageTrust(checks) {
|
|
166
|
+
const identityConsistent = checks.issuanceIdConsistent
|
|
167
|
+
&& checks.bondIdConsistent
|
|
168
|
+
&& checks.currencyConsistent
|
|
169
|
+
&& checks.controllerConsistent
|
|
170
|
+
&& checks.issuerEntityConsistent
|
|
171
|
+
&& checks.issuedPrincipalConsistent
|
|
172
|
+
&& checks.allTransitionIdentitiesMatch;
|
|
173
|
+
return {
|
|
174
|
+
...(0, reporting_1.buildLineageTrustBase)({
|
|
175
|
+
lineageKind: "state-history",
|
|
176
|
+
chainLength: checks.chainLength,
|
|
177
|
+
latestOrdinal: Math.max(0, checks.chainLength - 1),
|
|
178
|
+
allHashLinksVerified: checks.previousStateHashLinked && checks.allPreviousStateHashMatch,
|
|
179
|
+
identityConsistent,
|
|
180
|
+
fullLineageVerified: checks.fullHistoryVerified,
|
|
181
|
+
}),
|
|
182
|
+
latestStatus: checks.latestStatus,
|
|
183
|
+
startsAtGenesis: checks.startsAtGenesis,
|
|
184
|
+
previousStateHashLinked: checks.previousStateHashLinked,
|
|
185
|
+
issuanceIdConsistent: checks.issuanceIdConsistent,
|
|
186
|
+
bondIdConsistent: checks.bondIdConsistent,
|
|
187
|
+
currencyConsistent: checks.currencyConsistent,
|
|
188
|
+
controllerConsistent: checks.controllerConsistent,
|
|
189
|
+
issuerEntityConsistent: checks.issuerEntityConsistent,
|
|
190
|
+
issuedPrincipalConsistent: checks.issuedPrincipalConsistent,
|
|
191
|
+
allPreviousStateHashMatch: checks.allPreviousStateHashMatch,
|
|
192
|
+
allRedemptionArithmeticValid: checks.allRedemptionArithmeticValid,
|
|
193
|
+
allStatusProgressionValid: checks.allStatusProgressionValid,
|
|
194
|
+
allTransitionIdentitiesMatch: checks.allTransitionIdentitiesMatch,
|
|
195
|
+
fullHistoryVerified: checks.fullHistoryVerified,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
function buildEmptyBondDefinitionTrust() {
|
|
199
|
+
return {
|
|
200
|
+
artifactMatch: false,
|
|
201
|
+
onChainAnchorPresent: false,
|
|
202
|
+
onChainAnchorVerified: false,
|
|
203
|
+
effectiveMode: "none",
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
function buildEmptyBondStateTrust() {
|
|
207
|
+
return {
|
|
208
|
+
artifactMatch: false,
|
|
209
|
+
onChainAnchorPresent: false,
|
|
210
|
+
onChainAnchorVerified: false,
|
|
211
|
+
effectiveMode: "none",
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
function buildBaseBondReport(input) {
|
|
215
|
+
return (0, reporting_1.buildVerificationTrustSections)({
|
|
216
|
+
definitionTrust: input?.definitionTrust,
|
|
217
|
+
stateTrust: input?.stateTrust,
|
|
218
|
+
requireArtifactTrust: input?.requireArtifactTrust,
|
|
219
|
+
emptyDefinitionTrust: buildEmptyBondDefinitionTrust(),
|
|
220
|
+
emptyStateTrust: buildEmptyBondStateTrust(),
|
|
221
|
+
});
|
|
222
|
+
}
|
|
73
223
|
async function defineBond(sdk, input) {
|
|
74
224
|
const definitionSource = resolveValueOrPath({
|
|
75
225
|
pathValue: input.definitionPath,
|
|
@@ -102,7 +252,7 @@ async function defineBond(sdk, input) {
|
|
|
102
252
|
...(issuanceSource.jsonPath ? { jsonPath: issuanceSource.jsonPath } : { value: issuance }),
|
|
103
253
|
});
|
|
104
254
|
(0, bondValidation_1.validateBondCrossChecks)(definition, issuance);
|
|
105
|
-
const simfPath = input.simfPath ??
|
|
255
|
+
const simfPath = input.simfPath ?? resolveBondDocsAsset("bond-issuance-anchor.simf");
|
|
106
256
|
return sdk.compileFromFile({
|
|
107
257
|
simfPath,
|
|
108
258
|
templateVars: {
|
|
@@ -186,6 +336,15 @@ async function buildBondPayload(sdk, input) {
|
|
|
186
336
|
const definitionValue = (0, bondValidation_1.validateBondDefinition)(JSON.parse(verification.definition.definition.canonicalJson));
|
|
187
337
|
const issuanceValue = (0, bondValidation_1.validateBondIssuanceState)(JSON.parse(verification.issuance.state.canonicalJson));
|
|
188
338
|
const issuanceSummary = (0, bondValidation_1.summarizeBondIssuanceState)(issuanceValue);
|
|
339
|
+
const issuanceHistory = input.issuanceHistoryPaths || input.issuanceHistoryValues
|
|
340
|
+
? await loadIssuanceHistoryDocuments(sdk, {
|
|
341
|
+
issuanceHistoryPaths: input.issuanceHistoryPaths,
|
|
342
|
+
issuanceHistoryValues: input.issuanceHistoryValues,
|
|
343
|
+
})
|
|
344
|
+
: [];
|
|
345
|
+
const lineageChecks = issuanceHistory.length > 0
|
|
346
|
+
? (0, bondValidation_1.verifyBondIssuanceHistory)({ history: issuanceHistory.map((entry) => entry.value) })
|
|
347
|
+
: undefined;
|
|
189
348
|
return {
|
|
190
349
|
artifact: verification.artifact,
|
|
191
350
|
payload: {
|
|
@@ -218,6 +377,45 @@ async function buildBondPayload(sdk, input) {
|
|
|
218
377
|
trust: {
|
|
219
378
|
definitionTrust: verification.definition.trust,
|
|
220
379
|
issuanceTrust: verification.issuance.trust,
|
|
380
|
+
issuanceLineageTrust: lineageChecks ? buildBondIssuanceLineageTrust(lineageChecks) : undefined,
|
|
381
|
+
},
|
|
382
|
+
...(issuanceHistory.length > 0
|
|
383
|
+
? {
|
|
384
|
+
issuanceHistory: issuanceHistory.map((entry) => entry.state),
|
|
385
|
+
issuanceHistoryValues: issuanceHistory.map((entry) => entry.value),
|
|
386
|
+
issuanceHistorySummaries: issuanceHistory.map((entry) => entry.summary),
|
|
387
|
+
}
|
|
388
|
+
: {}),
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
async function verifyIssuanceHistory(sdk, input) {
|
|
392
|
+
const definitionSource = resolveValueOrPath({
|
|
393
|
+
pathValue: input.definitionPath,
|
|
394
|
+
objectValue: input.definitionValue,
|
|
395
|
+
});
|
|
396
|
+
const definition = input.definitionPath || input.definitionValue
|
|
397
|
+
? await sdk.loadDefinition({
|
|
398
|
+
type: "bond",
|
|
399
|
+
id: input.definitionValue?.bondId ?? "BOND-2026-001",
|
|
400
|
+
...definitionSource,
|
|
401
|
+
})
|
|
402
|
+
: undefined;
|
|
403
|
+
const definitionValue = definition ? (0, bondValidation_1.validateBondDefinition)(JSON.parse(definition.canonicalJson)) : undefined;
|
|
404
|
+
const issuanceHistory = await loadIssuanceHistoryDocuments(sdk, input);
|
|
405
|
+
const checks = (0, bondValidation_1.verifyBondIssuanceHistory)({ history: issuanceHistory.map((entry) => entry.value) });
|
|
406
|
+
if (definitionValue) {
|
|
407
|
+
(0, bondValidation_1.validateBondCrossChecks)(definitionValue, issuanceHistory.at(-1).value);
|
|
408
|
+
}
|
|
409
|
+
return {
|
|
410
|
+
verified: checks.fullHistoryVerified,
|
|
411
|
+
...(definition ? { definition, definitionValue } : {}),
|
|
412
|
+
issuanceHistory: issuanceHistory.map((entry) => entry.state),
|
|
413
|
+
issuanceHistoryValues: issuanceHistory.map((entry) => entry.value),
|
|
414
|
+
issuanceHistorySummaries: issuanceHistory.map((entry) => entry.summary),
|
|
415
|
+
checks,
|
|
416
|
+
report: {
|
|
417
|
+
...buildBaseBondReport({ requireArtifactTrust: true }),
|
|
418
|
+
issuanceLineageTrust: buildBondIssuanceLineageTrust(checks),
|
|
221
419
|
},
|
|
222
420
|
};
|
|
223
421
|
}
|
|
@@ -263,12 +461,223 @@ function bondStatusToCode(status) {
|
|
|
263
461
|
return 2;
|
|
264
462
|
case "REDEEMED":
|
|
265
463
|
return 3;
|
|
464
|
+
case "CLOSED":
|
|
465
|
+
return 4;
|
|
266
466
|
default: {
|
|
267
467
|
const exhaustiveCheck = status;
|
|
268
468
|
throw new Error(`Unsupported bond status: ${exhaustiveCheck}`);
|
|
269
469
|
}
|
|
270
470
|
}
|
|
271
471
|
}
|
|
472
|
+
function closingReasonToCode(reason) {
|
|
473
|
+
switch (reason) {
|
|
474
|
+
case "REDEEMED":
|
|
475
|
+
return 1;
|
|
476
|
+
case "CANCELLED":
|
|
477
|
+
return 2;
|
|
478
|
+
case "MATURED_OUT":
|
|
479
|
+
return 3;
|
|
480
|
+
default: {
|
|
481
|
+
const exhaustiveCheck = reason;
|
|
482
|
+
throw new Error(`Unsupported closing reason: ${exhaustiveCheck}`);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
function summarizeExpectedOutputDescriptor(descriptor) {
|
|
487
|
+
const canonicalJson = (0, summary_1.stableStringify)({
|
|
488
|
+
assetId: descriptor.assetId,
|
|
489
|
+
feeIndex: descriptor.feeIndex,
|
|
490
|
+
maxFeeSat: descriptor.maxFeeSat,
|
|
491
|
+
nextAmountSat: descriptor.nextAmountSat,
|
|
492
|
+
nextContractAddress: descriptor.nextContractAddress,
|
|
493
|
+
nextOutputHash: descriptor.nextOutputHash ?? null,
|
|
494
|
+
nextOutputScriptHash: descriptor.nextOutputScriptHash ?? null,
|
|
495
|
+
nextOutputIndex: descriptor.nextOutputIndex,
|
|
496
|
+
requestedOutputBindingMode: descriptor.requestedOutputBindingMode ?? descriptor.outputBindingMode ?? "none",
|
|
497
|
+
outputForm: descriptor.outputForm ?? (0, outputBinding_1.normalizeOutputForm)(),
|
|
498
|
+
rawOutput: (0, outputBinding_1.normalizeOutputRawFields)(descriptor.rawOutput) ?? null,
|
|
499
|
+
outputBindingMode: descriptor.outputBindingMode ?? "none",
|
|
500
|
+
});
|
|
501
|
+
return { canonicalJson, hash: (0, summary_1.sha256HexUtf8)(canonicalJson) };
|
|
502
|
+
}
|
|
503
|
+
function validateExpectedOutputDescriptor(descriptor) {
|
|
504
|
+
if (!descriptor.nextContractAddress || descriptor.nextContractAddress.trim().length === 0) {
|
|
505
|
+
throw new Error("nextContractAddress must be a non-empty string");
|
|
506
|
+
}
|
|
507
|
+
if (!descriptor.assetId || descriptor.assetId.trim().length === 0) {
|
|
508
|
+
throw new Error("assetId must be a non-empty string");
|
|
509
|
+
}
|
|
510
|
+
if (descriptor.nextOutputScriptHash !== undefined && descriptor.nextOutputScriptHash !== null) {
|
|
511
|
+
if (!/^[0-9a-f]{64}$/i.test(descriptor.nextOutputScriptHash)) {
|
|
512
|
+
throw new Error("nextOutputScriptHash must be a 64-character hex string");
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
if (descriptor.nextOutputHash !== undefined && descriptor.nextOutputHash !== null) {
|
|
516
|
+
if (!/^[0-9a-f]{64}$/i.test(descriptor.nextOutputHash)) {
|
|
517
|
+
throw new Error("nextOutputHash must be a 64-character hex string");
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
if (!Number.isInteger(descriptor.nextAmountSat) || descriptor.nextAmountSat <= 0) {
|
|
521
|
+
throw new Error("nextAmountSat must be a positive integer");
|
|
522
|
+
}
|
|
523
|
+
if (!Number.isInteger(descriptor.maxFeeSat) || descriptor.maxFeeSat < 0) {
|
|
524
|
+
throw new Error("maxFeeSat must be a non-negative integer");
|
|
525
|
+
}
|
|
526
|
+
if (!Number.isInteger(descriptor.nextOutputIndex) || descriptor.nextOutputIndex < 0) {
|
|
527
|
+
throw new Error("nextOutputIndex must be a non-negative integer");
|
|
528
|
+
}
|
|
529
|
+
if (!Number.isInteger(descriptor.feeIndex) || descriptor.feeIndex < 0) {
|
|
530
|
+
throw new Error("feeIndex must be a non-negative integer");
|
|
531
|
+
}
|
|
532
|
+
if (descriptor.requestedOutputBindingMode
|
|
533
|
+
&& descriptor.requestedOutputBindingMode !== "none"
|
|
534
|
+
&& descriptor.requestedOutputBindingMode !== "script-bound"
|
|
535
|
+
&& descriptor.requestedOutputBindingMode !== "descriptor-bound") {
|
|
536
|
+
throw new Error("requestedOutputBindingMode must be none, script-bound, or descriptor-bound");
|
|
537
|
+
}
|
|
538
|
+
if (descriptor.outputBindingMode !== "none"
|
|
539
|
+
&& descriptor.outputBindingMode !== "script-bound"
|
|
540
|
+
&& descriptor.outputBindingMode !== "descriptor-bound") {
|
|
541
|
+
throw new Error("outputBindingMode must be none, script-bound, or descriptor-bound");
|
|
542
|
+
}
|
|
543
|
+
descriptor.rawOutput = (0, outputBinding_1.normalizeOutputRawFields)(descriptor.rawOutput);
|
|
544
|
+
descriptor.outputForm = (0, outputBinding_1.normalizeOutputForm)(descriptor.outputForm);
|
|
545
|
+
descriptor.requestedOutputBindingMode = descriptor.requestedOutputBindingMode ?? descriptor.outputBindingMode ?? "none";
|
|
546
|
+
return descriptor;
|
|
547
|
+
}
|
|
548
|
+
async function buildExpectedOutputDescriptor(sdk, input) {
|
|
549
|
+
const definitionSource = resolveValueOrPath({
|
|
550
|
+
pathValue: input.definitionPath,
|
|
551
|
+
objectValue: input.definitionValue,
|
|
552
|
+
});
|
|
553
|
+
const nextSource = resolveValueOrPath({
|
|
554
|
+
pathValue: input.nextIssuancePath,
|
|
555
|
+
objectValue: input.nextIssuanceValue,
|
|
556
|
+
});
|
|
557
|
+
const definitionDescriptor = await sdk.loadDefinition({
|
|
558
|
+
type: "bond",
|
|
559
|
+
id: input.definitionValue?.bondId ?? "BOND-2026-001",
|
|
560
|
+
...definitionSource,
|
|
561
|
+
});
|
|
562
|
+
const nextDescriptor = await sdk.loadStateDocument({
|
|
563
|
+
type: "bond-issuance",
|
|
564
|
+
id: input.nextIssuanceValue?.issuanceId ?? "BOND-2026-001-ISSUE-1",
|
|
565
|
+
...nextSource,
|
|
566
|
+
});
|
|
567
|
+
const definition = (0, bondValidation_1.validateBondDefinition)(JSON.parse(definitionDescriptor.canonicalJson));
|
|
568
|
+
const next = (0, bondValidation_1.validateBondIssuanceState)(JSON.parse(nextDescriptor.canonicalJson));
|
|
569
|
+
(0, bondValidation_1.validateBondCrossChecks)(definition, next);
|
|
570
|
+
const nextStateCompiled = await defineBond(sdk, {
|
|
571
|
+
definitionValue: definition,
|
|
572
|
+
issuanceValue: next,
|
|
573
|
+
simfPath: input.nextStateSimfPath,
|
|
574
|
+
});
|
|
575
|
+
const nextScriptPubKeyHex = await (0, outputBinding_1.getScriptPubKeyHexViaRpc)(sdk, nextStateCompiled.deployment().contractAddress);
|
|
576
|
+
const nextOutputScriptHash = (0, outputBinding_1.hashHexBytes)(nextScriptPubKeyHex);
|
|
577
|
+
const requestedBindingMode = input.outputBindingMode ?? "script-bound";
|
|
578
|
+
const outputForm = (0, outputBinding_1.normalizeOutputForm)(input.outputForm);
|
|
579
|
+
const rawOutput = (0, outputBinding_1.normalizeOutputRawFields)(input.rawOutput);
|
|
580
|
+
const rawOutputAnalysis = (0, outputBinding_1.analyzeOutputRawFields)(rawOutput);
|
|
581
|
+
const explicitAssetHex = requestedBindingMode !== "none" && (0, outputBinding_1.isExplicitV1OutputForm)(outputForm)
|
|
582
|
+
? await (0, outputBinding_1.resolveExplicitAssetHex)(sdk, definition.currencyAssetId)
|
|
583
|
+
: undefined;
|
|
584
|
+
const autoDerivedNextOutputHash = requestedBindingMode === "descriptor-bound" && !input.nextOutputHash
|
|
585
|
+
? rawOutputAnalysis.valid && rawOutputAnalysis.normalized
|
|
586
|
+
? (0, outputBinding_1.computeRawOutputV1Hash)(rawOutputAnalysis.normalized)
|
|
587
|
+
: explicitAssetHex
|
|
588
|
+
? (0, outputBinding_1.computeExplicitV1OutputHash)({
|
|
589
|
+
assetHex: explicitAssetHex,
|
|
590
|
+
nextAmountSat: input.nextAmountSat,
|
|
591
|
+
nextOutputScriptHash,
|
|
592
|
+
})
|
|
593
|
+
: undefined
|
|
594
|
+
: undefined;
|
|
595
|
+
const nextOutputHash = input.nextOutputHash ?? autoDerivedNextOutputHash;
|
|
596
|
+
const bindingDecision = (0, outputBinding_1.resolveOutputBindingDecision)({
|
|
597
|
+
requestedBindingMode,
|
|
598
|
+
nextOutputHash,
|
|
599
|
+
nextOutputScriptHash,
|
|
600
|
+
autoDerivedNextOutputHash: Boolean(autoDerivedNextOutputHash && !input.nextOutputHash),
|
|
601
|
+
explicitAssetSupported: Boolean(explicitAssetHex),
|
|
602
|
+
outputForm,
|
|
603
|
+
rawOutput,
|
|
604
|
+
});
|
|
605
|
+
const descriptor = validateExpectedOutputDescriptor({
|
|
606
|
+
nextContractAddress: nextStateCompiled.deployment().contractAddress,
|
|
607
|
+
nextOutputHash: bindingDecision.outputBindingMode === "descriptor-bound" ? nextOutputHash : undefined,
|
|
608
|
+
nextOutputScriptHash: bindingDecision.outputBindingMode !== "none" ? nextOutputScriptHash : undefined,
|
|
609
|
+
nextAmountSat: input.nextAmountSat,
|
|
610
|
+
assetId: definition.currencyAssetId,
|
|
611
|
+
requestedOutputBindingMode: requestedBindingMode,
|
|
612
|
+
outputForm,
|
|
613
|
+
rawOutput,
|
|
614
|
+
feeIndex: input.feeIndex ?? 1,
|
|
615
|
+
nextOutputIndex: input.nextOutputIndex ?? 0,
|
|
616
|
+
maxFeeSat: input.maxFeeSat ?? 100,
|
|
617
|
+
outputBindingMode: bindingDecision.outputBindingMode,
|
|
618
|
+
});
|
|
619
|
+
const summary = summarizeExpectedOutputDescriptor(descriptor);
|
|
620
|
+
return {
|
|
621
|
+
descriptor,
|
|
622
|
+
canonicalJson: summary.canonicalJson,
|
|
623
|
+
hash: summary.hash,
|
|
624
|
+
supportedForm: bindingDecision.supportedForm,
|
|
625
|
+
reasonCode: bindingDecision.reasonCode,
|
|
626
|
+
autoDerivedNextOutputHash: bindingDecision.autoDerived,
|
|
627
|
+
fallbackReason: bindingDecision.fallbackReason,
|
|
628
|
+
bindingInputs: {
|
|
629
|
+
assetId: descriptor.assetId,
|
|
630
|
+
assetForm: descriptor.outputForm?.assetForm ?? "explicit",
|
|
631
|
+
amountForm: descriptor.outputForm?.amountForm ?? "explicit",
|
|
632
|
+
nonceForm: descriptor.outputForm?.nonceForm ?? "null",
|
|
633
|
+
rangeProofForm: descriptor.outputForm?.rangeProofForm ?? "empty",
|
|
634
|
+
nextAmountSat: descriptor.nextAmountSat,
|
|
635
|
+
nextOutputIndex: descriptor.nextOutputIndex,
|
|
636
|
+
feeIndex: descriptor.feeIndex,
|
|
637
|
+
maxFeeSat: descriptor.maxFeeSat,
|
|
638
|
+
...(rawOutputAnalysis.valid && rawOutputAnalysis.normalized
|
|
639
|
+
? {
|
|
640
|
+
rawOutputComponents: {
|
|
641
|
+
scriptPubKey: rawOutputAnalysis.normalized.scriptComponentSource,
|
|
642
|
+
rangeProof: rawOutputAnalysis.normalized.rangeProofComponentSource,
|
|
643
|
+
},
|
|
644
|
+
}
|
|
645
|
+
: {}),
|
|
646
|
+
},
|
|
647
|
+
};
|
|
648
|
+
}
|
|
649
|
+
async function verifyExpectedOutputDescriptor(sdk, input) {
|
|
650
|
+
const actual = validateExpectedOutputDescriptor(input.descriptorValue);
|
|
651
|
+
const expected = await buildExpectedOutputDescriptor(sdk, {
|
|
652
|
+
definitionPath: input.definitionPath,
|
|
653
|
+
definitionValue: input.definitionValue,
|
|
654
|
+
nextIssuancePath: input.nextIssuancePath,
|
|
655
|
+
nextIssuanceValue: input.nextIssuanceValue,
|
|
656
|
+
nextStateSimfPath: input.nextStateSimfPath,
|
|
657
|
+
nextAmountSat: input.nextAmountSat ?? actual.nextAmountSat,
|
|
658
|
+
maxFeeSat: input.maxFeeSat ?? actual.maxFeeSat,
|
|
659
|
+
nextOutputIndex: input.nextOutputIndex ?? actual.nextOutputIndex,
|
|
660
|
+
feeIndex: input.feeIndex ?? actual.feeIndex,
|
|
661
|
+
nextOutputHash: input.nextOutputHash ?? actual.nextOutputHash,
|
|
662
|
+
outputForm: input.outputForm ?? actual.outputForm,
|
|
663
|
+
rawOutput: input.rawOutput ?? actual.rawOutput,
|
|
664
|
+
outputBindingMode: input.outputBindingMode ?? actual.outputBindingMode,
|
|
665
|
+
});
|
|
666
|
+
const actualSummary = summarizeExpectedOutputDescriptor(actual);
|
|
667
|
+
return {
|
|
668
|
+
ok: actualSummary.hash === expected.hash,
|
|
669
|
+
reason: actualSummary.hash === expected.hash ? undefined : "Expected output descriptor hash mismatch",
|
|
670
|
+
descriptor: actual,
|
|
671
|
+
expected: expected.descriptor,
|
|
672
|
+
hash: actualSummary.hash,
|
|
673
|
+
expectedHash: expected.hash,
|
|
674
|
+
supportedForm: expected.supportedForm,
|
|
675
|
+
reasonCode: expected.reasonCode,
|
|
676
|
+
autoDerivedNextOutputHash: expected.autoDerivedNextOutputHash,
|
|
677
|
+
fallbackReason: expected.fallbackReason,
|
|
678
|
+
bindingInputs: expected.bindingInputs,
|
|
679
|
+
};
|
|
680
|
+
}
|
|
272
681
|
async function redeemBond(sdk, input) {
|
|
273
682
|
const definitionSource = resolveValueOrPath({
|
|
274
683
|
pathValue: input.definitionPath,
|
|
@@ -307,7 +716,7 @@ async function redeemBond(sdk, input) {
|
|
|
307
716
|
id: nextIssuance.issuanceId,
|
|
308
717
|
value: nextIssuance,
|
|
309
718
|
});
|
|
310
|
-
const simfPath = input.simfPath ??
|
|
719
|
+
const simfPath = input.simfPath ?? resolveBondDocsAsset("bond-issuance-anchor.simf");
|
|
311
720
|
return sdk.compileFromFile({
|
|
312
721
|
simfPath,
|
|
313
722
|
templateVars: {
|
|
@@ -413,6 +822,17 @@ async function buildBondSettlementDescriptor(sdk, input) {
|
|
|
413
822
|
issuanceValue: transition.next,
|
|
414
823
|
simfPath: input.nextStateSimfPath,
|
|
415
824
|
});
|
|
825
|
+
const expectedOutputDescriptor = await buildExpectedOutputDescriptor(sdk, {
|
|
826
|
+
definitionValue: transition.definition,
|
|
827
|
+
nextIssuanceValue: transition.next,
|
|
828
|
+
nextStateSimfPath: input.nextStateSimfPath,
|
|
829
|
+
nextAmountSat: input.nextAmountSat,
|
|
830
|
+
maxFeeSat: input.maxFeeSat ?? 100,
|
|
831
|
+
nextOutputHash: input.nextOutputHash,
|
|
832
|
+
outputForm: input.outputForm,
|
|
833
|
+
rawOutput: input.rawOutput,
|
|
834
|
+
outputBindingMode: input.outputBindingMode,
|
|
835
|
+
});
|
|
416
836
|
const nextContractAddress = nextStateCompiled.deployment().contractAddress;
|
|
417
837
|
const descriptor = (0, bondSettlementValidation_1.validateBondSettlementDescriptor)({
|
|
418
838
|
settlementId: `${transition.previous.issuanceId}-SETTLEMENT-${transition.payload.nextStatus}`,
|
|
@@ -430,6 +850,8 @@ async function buildBondSettlementDescriptor(sdk, input) {
|
|
|
430
850
|
nextContractAddress,
|
|
431
851
|
nextAmountSat: input.nextAmountSat,
|
|
432
852
|
maxFeeSat: input.maxFeeSat ?? 100,
|
|
853
|
+
expectedOutputDescriptorHash: expectedOutputDescriptor.hash,
|
|
854
|
+
outputBindingMode: expectedOutputDescriptor.descriptor.outputBindingMode ?? "none",
|
|
433
855
|
principal: {
|
|
434
856
|
issued: transition.payload.principal.issued,
|
|
435
857
|
previousOutstanding: transition.payload.principal.previousOutstanding,
|
|
@@ -446,6 +868,13 @@ async function buildBondSettlementDescriptor(sdk, input) {
|
|
|
446
868
|
transition: transition.payload.crossChecks.transition,
|
|
447
869
|
nextContractAddress,
|
|
448
870
|
descriptor,
|
|
871
|
+
expectedOutputDescriptor: expectedOutputDescriptor.descriptor,
|
|
872
|
+
expectedOutputDescriptorHash: expectedOutputDescriptor.hash,
|
|
873
|
+
expectedOutputBindingSupportedForm: expectedOutputDescriptor.supportedForm,
|
|
874
|
+
expectedOutputBindingReasonCode: expectedOutputDescriptor.reasonCode,
|
|
875
|
+
expectedOutputBindingAutoDerived: expectedOutputDescriptor.autoDerivedNextOutputHash,
|
|
876
|
+
expectedOutputBindingFallbackReason: expectedOutputDescriptor.fallbackReason,
|
|
877
|
+
expectedOutputBindingInputs: expectedOutputDescriptor.bindingInputs,
|
|
449
878
|
canonicalJson: summary.canonicalJson,
|
|
450
879
|
hash: summary.hash,
|
|
451
880
|
};
|
|
@@ -468,6 +897,10 @@ async function verifyBondSettlementDescriptor(sdk, input) {
|
|
|
468
897
|
nextStateSimfPath: input.nextStateSimfPath,
|
|
469
898
|
nextAmountSat: input.nextAmountSat ?? descriptor.nextAmountSat,
|
|
470
899
|
maxFeeSat: input.maxFeeSat ?? descriptor.maxFeeSat,
|
|
900
|
+
nextOutputHash: input.nextOutputHash,
|
|
901
|
+
outputForm: input.outputForm,
|
|
902
|
+
rawOutput: input.rawOutput,
|
|
903
|
+
outputBindingMode: descriptor.outputBindingMode,
|
|
471
904
|
});
|
|
472
905
|
const actualSummary = (0, bondSettlementValidation_1.summarizeBondSettlementDescriptor)(descriptor);
|
|
473
906
|
const matches = (0, bondSettlementValidation_1.validateBondSettlementMatchesExpected)(descriptor, expected.descriptor);
|
|
@@ -479,6 +912,11 @@ async function verifyBondSettlementDescriptor(sdk, input) {
|
|
|
479
912
|
hash: actualSummary.hash,
|
|
480
913
|
expectedHash: expected.hash,
|
|
481
914
|
matches,
|
|
915
|
+
supportedForm: expected.expectedOutputBindingSupportedForm,
|
|
916
|
+
reasonCode: expected.expectedOutputBindingReasonCode,
|
|
917
|
+
autoDerivedNextOutputHash: expected.expectedOutputBindingAutoDerived,
|
|
918
|
+
fallbackReason: expected.expectedOutputBindingFallbackReason,
|
|
919
|
+
bindingInputs: expected.expectedOutputBindingInputs,
|
|
482
920
|
};
|
|
483
921
|
}
|
|
484
922
|
async function buildBondSettlementPayload(sdk, input) {
|
|
@@ -486,6 +924,13 @@ async function buildBondSettlementPayload(sdk, input) {
|
|
|
486
924
|
return {
|
|
487
925
|
descriptor: result.descriptor,
|
|
488
926
|
descriptorHash: result.hash,
|
|
927
|
+
expectedOutputDescriptor: result.expectedOutputDescriptor,
|
|
928
|
+
expectedOutputDescriptorHash: result.expectedOutputDescriptorHash,
|
|
929
|
+
supportedForm: result.expectedOutputBindingSupportedForm,
|
|
930
|
+
reasonCode: result.expectedOutputBindingReasonCode,
|
|
931
|
+
autoDerivedNextOutputHash: result.expectedOutputBindingAutoDerived,
|
|
932
|
+
fallbackReason: result.expectedOutputBindingFallbackReason,
|
|
933
|
+
bindingInputs: result.expectedOutputBindingInputs,
|
|
489
934
|
previousStateHash: result.descriptor.previousStateHash,
|
|
490
935
|
nextStateHash: result.descriptor.nextStateHash,
|
|
491
936
|
nextContractAddress: result.descriptor.nextContractAddress,
|
|
@@ -493,6 +938,440 @@ async function buildBondSettlementPayload(sdk, input) {
|
|
|
493
938
|
maxFeeSat: result.descriptor.maxFeeSat,
|
|
494
939
|
};
|
|
495
940
|
}
|
|
941
|
+
async function buildBondClosing(sdk, input) {
|
|
942
|
+
const definitionSource = resolveValueOrPath({
|
|
943
|
+
pathValue: input.definitionPath,
|
|
944
|
+
objectValue: input.definitionValue,
|
|
945
|
+
});
|
|
946
|
+
const issuanceSource = resolveValueOrPath({
|
|
947
|
+
pathValue: input.redeemedIssuancePath,
|
|
948
|
+
objectValue: input.redeemedIssuanceValue,
|
|
949
|
+
});
|
|
950
|
+
const definitionDescriptor = await sdk.loadDefinition({
|
|
951
|
+
type: "bond",
|
|
952
|
+
id: input.definitionValue?.bondId ?? "BOND-2026-001",
|
|
953
|
+
...definitionSource,
|
|
954
|
+
});
|
|
955
|
+
const issuanceDescriptor = await sdk.loadStateDocument({
|
|
956
|
+
type: "bond-issuance",
|
|
957
|
+
id: input.redeemedIssuanceValue?.issuanceId ?? "BOND-2026-001-ISSUE-1",
|
|
958
|
+
...issuanceSource,
|
|
959
|
+
});
|
|
960
|
+
const definition = (0, bondValidation_1.validateBondDefinition)(JSON.parse(definitionDescriptor.canonicalJson));
|
|
961
|
+
const redeemed = (0, bondValidation_1.validateBondIssuanceState)(JSON.parse(issuanceDescriptor.canonicalJson));
|
|
962
|
+
(0, bondValidation_1.validateBondCrossChecks)(definition, redeemed);
|
|
963
|
+
const settlementVerification = await verifyBondSettlementDescriptor(sdk, {
|
|
964
|
+
descriptorPath: input.settlementDescriptorPath,
|
|
965
|
+
descriptorValue: input.settlementDescriptorValue,
|
|
966
|
+
definitionValue: definition,
|
|
967
|
+
previousIssuanceValue: undefined,
|
|
968
|
+
nextIssuanceValue: redeemed,
|
|
969
|
+
nextAmountSat: input.settlementDescriptorValue?.nextAmountSat,
|
|
970
|
+
maxFeeSat: input.settlementDescriptorValue?.maxFeeSat,
|
|
971
|
+
}).catch(() => undefined);
|
|
972
|
+
const finalSettlementDescriptorHash = settlementVerification?.hash
|
|
973
|
+
?? (input.settlementDescriptorValue
|
|
974
|
+
? (0, bondSettlementValidation_1.summarizeBondSettlementDescriptor)(input.settlementDescriptorValue).hash
|
|
975
|
+
: undefined);
|
|
976
|
+
if (!finalSettlementDescriptorHash) {
|
|
977
|
+
throw new Error("A valid settlement descriptor is required to build a closing state");
|
|
978
|
+
}
|
|
979
|
+
const closed = (0, bondValidation_1.buildClosedBondIssuanceState)({
|
|
980
|
+
previous: redeemed,
|
|
981
|
+
closedAt: input.closedAt,
|
|
982
|
+
closingReason: input.closingReason ?? "REDEEMED",
|
|
983
|
+
finalSettlementDescriptorHash,
|
|
984
|
+
});
|
|
985
|
+
const closing = {
|
|
986
|
+
closingId: `${closed.issuanceId}-CLOSE`,
|
|
987
|
+
bondId: definition.bondId,
|
|
988
|
+
issuanceId: closed.issuanceId,
|
|
989
|
+
finalStatus: "CLOSED",
|
|
990
|
+
definitionHash: definitionDescriptor.hash,
|
|
991
|
+
previousStateHash: (0, bondValidation_1.summarizeBondIssuanceState)(redeemed).hash,
|
|
992
|
+
closedStateHash: (0, bondValidation_1.summarizeBondIssuanceState)(closed).hash,
|
|
993
|
+
stateHash: (0, bondValidation_1.summarizeBondIssuanceState)(closed).hash,
|
|
994
|
+
closedAt: input.closedAt,
|
|
995
|
+
closingReason: input.closingReason ?? "REDEEMED",
|
|
996
|
+
finalSettlementDescriptorHash,
|
|
997
|
+
};
|
|
998
|
+
return {
|
|
999
|
+
definition,
|
|
1000
|
+
previous: redeemed,
|
|
1001
|
+
closed,
|
|
1002
|
+
closing,
|
|
1003
|
+
closingHash: (0, summary_1.sha256HexUtf8)((0, summary_1.stableStringify)(closing)),
|
|
1004
|
+
};
|
|
1005
|
+
}
|
|
1006
|
+
async function verifyBondClosing(sdk, input) {
|
|
1007
|
+
const definitionSource = resolveValueOrPath({
|
|
1008
|
+
pathValue: input.definitionPath,
|
|
1009
|
+
objectValue: input.definitionValue,
|
|
1010
|
+
});
|
|
1011
|
+
const redeemedSource = resolveValueOrPath({
|
|
1012
|
+
pathValue: input.redeemedIssuancePath,
|
|
1013
|
+
objectValue: input.redeemedIssuanceValue,
|
|
1014
|
+
});
|
|
1015
|
+
const closedSource = resolveValueOrPath({
|
|
1016
|
+
pathValue: input.closedIssuancePath,
|
|
1017
|
+
objectValue: input.closedIssuanceValue,
|
|
1018
|
+
});
|
|
1019
|
+
const definitionDescriptor = await sdk.loadDefinition({
|
|
1020
|
+
type: "bond",
|
|
1021
|
+
id: input.definitionValue?.bondId ?? "BOND-2026-001",
|
|
1022
|
+
...definitionSource,
|
|
1023
|
+
});
|
|
1024
|
+
const redeemedDescriptor = await sdk.loadStateDocument({
|
|
1025
|
+
type: "bond-issuance",
|
|
1026
|
+
id: input.redeemedIssuanceValue?.issuanceId ?? "BOND-2026-001-ISSUE-1",
|
|
1027
|
+
...redeemedSource,
|
|
1028
|
+
});
|
|
1029
|
+
const closedDescriptor = await sdk.loadStateDocument({
|
|
1030
|
+
type: "bond-issuance",
|
|
1031
|
+
id: input.closedIssuanceValue?.issuanceId ?? "BOND-2026-001-ISSUE-1",
|
|
1032
|
+
...closedSource,
|
|
1033
|
+
});
|
|
1034
|
+
const definition = (0, bondValidation_1.validateBondDefinition)(JSON.parse(definitionDescriptor.canonicalJson));
|
|
1035
|
+
const redeemed = (0, bondValidation_1.validateBondIssuanceState)(JSON.parse(redeemedDescriptor.canonicalJson));
|
|
1036
|
+
const closed = (0, bondValidation_1.validateBondIssuanceState)(JSON.parse(closedDescriptor.canonicalJson));
|
|
1037
|
+
(0, bondValidation_1.validateBondCrossChecks)(definition, redeemed);
|
|
1038
|
+
(0, bondValidation_1.validateBondCrossChecks)(definition, closed);
|
|
1039
|
+
const settlementHash = input.settlementDescriptorValue
|
|
1040
|
+
? (0, bondSettlementValidation_1.summarizeBondSettlementDescriptor)(input.settlementDescriptorValue).hash
|
|
1041
|
+
: input.settlementDescriptorPath
|
|
1042
|
+
? (0, bondSettlementValidation_1.summarizeBondSettlementDescriptor)(JSON.parse(await Promise.resolve().then(() => __importStar(require("node:fs/promises"))).then((fs) => fs.readFile(input.settlementDescriptorPath, "utf8")))).hash
|
|
1043
|
+
: "";
|
|
1044
|
+
const checks = {
|
|
1045
|
+
redeemedStateMatch: redeemed.status === "REDEEMED",
|
|
1046
|
+
closedStateMatch: closed.status === "CLOSED",
|
|
1047
|
+
previousStateHashMatch: closed.previousStateHash === (0, bondValidation_1.summarizeBondIssuanceState)(redeemed).hash,
|
|
1048
|
+
finalSettlementDescriptorHashMatch: closed.finalSettlementDescriptorHash === settlementHash,
|
|
1049
|
+
closingReasonPresent: !!closed.closingReason,
|
|
1050
|
+
closedAtPresent: !!closed.closedAt,
|
|
1051
|
+
};
|
|
1052
|
+
return {
|
|
1053
|
+
definition,
|
|
1054
|
+
redeemed,
|
|
1055
|
+
closed,
|
|
1056
|
+
checks,
|
|
1057
|
+
verified: Object.values(checks).every(Boolean),
|
|
1058
|
+
};
|
|
1059
|
+
}
|
|
1060
|
+
async function buildEvidenceBundle(sdk, input) {
|
|
1061
|
+
const artifact = input.artifact ?? (input.artifactPath ? (await sdk.loadArtifact(input.artifactPath)).artifact : undefined);
|
|
1062
|
+
if (!artifact)
|
|
1063
|
+
throw new Error("artifactPath or artifact is required");
|
|
1064
|
+
const verification = await verifyBond(sdk, {
|
|
1065
|
+
artifact,
|
|
1066
|
+
definitionPath: input.definitionPath,
|
|
1067
|
+
definitionValue: input.definitionValue,
|
|
1068
|
+
issuancePath: input.issuancePath,
|
|
1069
|
+
issuanceValue: input.issuanceValue,
|
|
1070
|
+
});
|
|
1071
|
+
const definition = verification.definition.definition;
|
|
1072
|
+
const issuance = verification.issuance.state;
|
|
1073
|
+
const issuanceHistory = input.issuanceHistoryPaths || input.issuanceHistoryValues
|
|
1074
|
+
? await loadIssuanceHistoryDocuments(sdk, {
|
|
1075
|
+
issuanceHistoryPaths: input.issuanceHistoryPaths,
|
|
1076
|
+
issuanceHistoryValues: input.issuanceHistoryValues,
|
|
1077
|
+
})
|
|
1078
|
+
: [];
|
|
1079
|
+
const lineageChecks = issuanceHistory.length > 0
|
|
1080
|
+
? (0, bondValidation_1.verifyBondIssuanceHistory)({ history: issuanceHistory.map((entry) => entry.value) })
|
|
1081
|
+
: undefined;
|
|
1082
|
+
const settlementCanonicalJson = input.settlementDescriptorValue
|
|
1083
|
+
? (0, bondSettlementValidation_1.summarizeBondSettlementDescriptor)(input.settlementDescriptorValue).canonicalJson
|
|
1084
|
+
: null;
|
|
1085
|
+
const settlementHash = input.settlementDescriptorValue
|
|
1086
|
+
? (0, bondSettlementValidation_1.summarizeBondSettlementDescriptor)(input.settlementDescriptorValue).hash
|
|
1087
|
+
: null;
|
|
1088
|
+
const closingCanonicalJson = input.closingDescriptorValue
|
|
1089
|
+
? (0, summary_1.stableStringify)(input.closingDescriptorValue)
|
|
1090
|
+
: null;
|
|
1091
|
+
const closingHash = closingCanonicalJson
|
|
1092
|
+
? (0, summary_1.sha256HexUtf8)(closingCanonicalJson)
|
|
1093
|
+
: null;
|
|
1094
|
+
const sourcePath = artifact.source.mode === "file" ? artifact.source.simfPath : undefined;
|
|
1095
|
+
const renderedSourceHash = sourcePath && (0, node_fs_1.existsSync)(sourcePath)
|
|
1096
|
+
? (0, summary_1.sha256HexUtf8)(await Promise.resolve().then(() => __importStar(require("node:fs/promises"))).then((fs) => fs.readFile(sourcePath, "utf8")))
|
|
1097
|
+
: null;
|
|
1098
|
+
return {
|
|
1099
|
+
artifact,
|
|
1100
|
+
definition: {
|
|
1101
|
+
canonicalJson: definition.canonicalJson,
|
|
1102
|
+
hash: definition.hash,
|
|
1103
|
+
},
|
|
1104
|
+
issuance: {
|
|
1105
|
+
canonicalJson: issuance.canonicalJson,
|
|
1106
|
+
hash: issuance.hash,
|
|
1107
|
+
},
|
|
1108
|
+
transition: input.transitionValue
|
|
1109
|
+
? {
|
|
1110
|
+
canonicalJson: (0, summary_1.stableStringify)(input.transitionValue),
|
|
1111
|
+
hash: (0, summary_1.sha256HexUtf8)((0, summary_1.stableStringify)(input.transitionValue)),
|
|
1112
|
+
}
|
|
1113
|
+
: undefined,
|
|
1114
|
+
settlement: settlementCanonicalJson && settlementHash
|
|
1115
|
+
? {
|
|
1116
|
+
canonicalJson: settlementCanonicalJson,
|
|
1117
|
+
hash: settlementHash,
|
|
1118
|
+
}
|
|
1119
|
+
: undefined,
|
|
1120
|
+
closing: closingCanonicalJson && closingHash
|
|
1121
|
+
? {
|
|
1122
|
+
canonicalJson: closingCanonicalJson,
|
|
1123
|
+
hash: closingHash,
|
|
1124
|
+
}
|
|
1125
|
+
: undefined,
|
|
1126
|
+
trust: {
|
|
1127
|
+
...buildBaseBondReport({
|
|
1128
|
+
definitionTrust: verification.definition.trust,
|
|
1129
|
+
stateTrust: verification.issuance.trust,
|
|
1130
|
+
}),
|
|
1131
|
+
issuanceLineageTrust: lineageChecks ? buildBondIssuanceLineageTrust(lineageChecks) : undefined,
|
|
1132
|
+
settlementTrust: input.settlementDescriptorValue
|
|
1133
|
+
? {
|
|
1134
|
+
descriptorHashMatch: true,
|
|
1135
|
+
outputBindingMode: input.settlementDescriptorValue.outputBindingMode ?? "none",
|
|
1136
|
+
}
|
|
1137
|
+
: undefined,
|
|
1138
|
+
},
|
|
1139
|
+
trustSummary: (0, reporting_1.buildVerificationTrustSummary)({
|
|
1140
|
+
definitionTrust: verification.definition.trust,
|
|
1141
|
+
stateTrust: verification.issuance.trust,
|
|
1142
|
+
bindingMode: input.settlementDescriptorValue?.outputBindingMode ?? "none",
|
|
1143
|
+
lineageTrust: lineageChecks ? buildBondIssuanceLineageTrust(lineageChecks) : undefined,
|
|
1144
|
+
}),
|
|
1145
|
+
renderedSourceHash: renderedSourceHash ?? undefined,
|
|
1146
|
+
sourceVerificationMode: renderedSourceHash ? "source-reloaded" : "artifact-only",
|
|
1147
|
+
compiled: {
|
|
1148
|
+
program: artifact.compiled.program,
|
|
1149
|
+
cmr: artifact.compiled.cmr,
|
|
1150
|
+
contractAddress: artifact.compiled.contractAddress,
|
|
1151
|
+
},
|
|
1152
|
+
};
|
|
1153
|
+
}
|
|
1154
|
+
async function verifyEvidenceBundle(sdk, input) {
|
|
1155
|
+
const expected = await buildEvidenceBundle(sdk, {
|
|
1156
|
+
artifact: input.bundleValue.artifact,
|
|
1157
|
+
definitionPath: input.definitionPath,
|
|
1158
|
+
issuancePath: input.issuancePath,
|
|
1159
|
+
settlementDescriptorValue: input.settlementDescriptorValue,
|
|
1160
|
+
closingDescriptorValue: input.closingDescriptorValue,
|
|
1161
|
+
});
|
|
1162
|
+
const checks = {
|
|
1163
|
+
definitionHashMatch: input.bundleValue.definition.hash === expected.definition.hash,
|
|
1164
|
+
issuanceHashMatch: input.bundleValue.issuance.hash === expected.issuance.hash,
|
|
1165
|
+
settlementHashMatch: (input.bundleValue.settlement?.hash ?? null) === (expected.settlement?.hash ?? null),
|
|
1166
|
+
closingHashMatch: (input.bundleValue.closing?.hash ?? null) === (expected.closing?.hash ?? null),
|
|
1167
|
+
renderedSourceHashMatch: input.bundleValue.renderedSourceHash === expected.renderedSourceHash,
|
|
1168
|
+
cmrMatch: input.bundleValue.compiled.cmr === expected.compiled.cmr,
|
|
1169
|
+
contractAddressMatch: input.bundleValue.compiled.contractAddress === expected.compiled.contractAddress,
|
|
1170
|
+
};
|
|
1171
|
+
return {
|
|
1172
|
+
expected,
|
|
1173
|
+
checks,
|
|
1174
|
+
verified: Object.values(checks).every(Boolean),
|
|
1175
|
+
};
|
|
1176
|
+
}
|
|
1177
|
+
async function issueBond(sdk, input) {
|
|
1178
|
+
return defineBond(sdk, input);
|
|
1179
|
+
}
|
|
1180
|
+
async function prepareRedemption(sdk, input) {
|
|
1181
|
+
const preview = await buildBondRedemption(sdk, {
|
|
1182
|
+
definitionPath: input.definitionPath,
|
|
1183
|
+
definitionValue: input.definitionValue,
|
|
1184
|
+
previousIssuancePath: input.previousIssuancePath,
|
|
1185
|
+
previousIssuanceValue: input.previousIssuanceValue,
|
|
1186
|
+
amount: input.amount,
|
|
1187
|
+
redeemedAt: input.redeemedAt,
|
|
1188
|
+
});
|
|
1189
|
+
const settlement = await buildBondSettlementPayload(sdk, {
|
|
1190
|
+
definitionValue: preview.definition,
|
|
1191
|
+
previousIssuanceValue: preview.previous,
|
|
1192
|
+
nextIssuanceValue: preview.next,
|
|
1193
|
+
nextStateSimfPath: input.nextStateSimfPath,
|
|
1194
|
+
nextAmountSat: input.nextAmountSat,
|
|
1195
|
+
maxFeeSat: input.maxFeeSat,
|
|
1196
|
+
nextOutputHash: input.nextOutputHash,
|
|
1197
|
+
rawOutput: input.rawOutput,
|
|
1198
|
+
outputBindingMode: input.outputBindingMode,
|
|
1199
|
+
});
|
|
1200
|
+
return { preview, settlement };
|
|
1201
|
+
}
|
|
1202
|
+
async function finalizeRedemption(sdk, input) {
|
|
1203
|
+
return buildBondMachineSettlementPlan(sdk, input);
|
|
1204
|
+
}
|
|
1205
|
+
async function prepareClosing(sdk, input) {
|
|
1206
|
+
return buildBondClosing(sdk, input);
|
|
1207
|
+
}
|
|
1208
|
+
async function exportFinalityPayload(sdk, input) {
|
|
1209
|
+
const bondPayload = await buildBondPayload(sdk, input);
|
|
1210
|
+
const evidence = await buildEvidenceBundle(sdk, input);
|
|
1211
|
+
return {
|
|
1212
|
+
payload: bondPayload.payload,
|
|
1213
|
+
bindingMode: input.settlementDescriptorValue?.outputBindingMode ?? "none",
|
|
1214
|
+
trust: bondPayload.trust,
|
|
1215
|
+
trustSummary: evidence.trustSummary,
|
|
1216
|
+
evidenceSummary: {
|
|
1217
|
+
definitionHash: evidence.definition.hash,
|
|
1218
|
+
issuanceHash: evidence.issuance.hash,
|
|
1219
|
+
settlementHash: evidence.settlement?.hash ?? null,
|
|
1220
|
+
closingHash: evidence.closing?.hash ?? null,
|
|
1221
|
+
renderedSourceHash: evidence.renderedSourceHash,
|
|
1222
|
+
sourceVerificationMode: evidence.sourceVerificationMode,
|
|
1223
|
+
},
|
|
1224
|
+
};
|
|
1225
|
+
}
|
|
1226
|
+
async function define(sdk, input) {
|
|
1227
|
+
return defineBond(sdk, input);
|
|
1228
|
+
}
|
|
1229
|
+
async function verify(sdk, input) {
|
|
1230
|
+
return verifyBond(sdk, input);
|
|
1231
|
+
}
|
|
1232
|
+
async function load(sdk, input) {
|
|
1233
|
+
return loadBond(sdk, input);
|
|
1234
|
+
}
|
|
1235
|
+
async function issue(sdk, input) {
|
|
1236
|
+
return issueBond(sdk, input);
|
|
1237
|
+
}
|
|
1238
|
+
async function buildSettlement(sdk, input) {
|
|
1239
|
+
return buildBondSettlementPayload(sdk, input);
|
|
1240
|
+
}
|
|
1241
|
+
async function verifySettlement(sdk, input) {
|
|
1242
|
+
return verifyBondSettlementDescriptor(sdk, input);
|
|
1243
|
+
}
|
|
1244
|
+
function resolveRedemptionBindingMode(settlement) {
|
|
1245
|
+
return settlement.descriptor?.outputBindingMode ?? "none";
|
|
1246
|
+
}
|
|
1247
|
+
async function inspectRedemption(sdk, input) {
|
|
1248
|
+
const settlement = await buildBondSettlementPayload(sdk, {
|
|
1249
|
+
definitionPath: input.definitionPath,
|
|
1250
|
+
definitionValue: input.definitionValue,
|
|
1251
|
+
previousIssuancePath: input.previousIssuancePath,
|
|
1252
|
+
previousIssuanceValue: input.previousIssuanceValue,
|
|
1253
|
+
nextIssuancePath: input.nextIssuancePath,
|
|
1254
|
+
nextIssuanceValue: input.nextIssuanceValue,
|
|
1255
|
+
nextStateSimfPath: input.nextStateSimfPath,
|
|
1256
|
+
nextAmountSat: input.nextAmountSat ?? 1900,
|
|
1257
|
+
maxFeeSat: input.maxFeeSat,
|
|
1258
|
+
nextOutputHash: input.nextOutputHash,
|
|
1259
|
+
outputForm: input.outputForm,
|
|
1260
|
+
rawOutput: input.rawOutput,
|
|
1261
|
+
outputBindingMode: input.outputBindingMode,
|
|
1262
|
+
});
|
|
1263
|
+
const mode = resolveRedemptionBindingMode(settlement);
|
|
1264
|
+
if (mode === "descriptor-bound") {
|
|
1265
|
+
const result = await inspectBondDescriptorBoundMachineRollover(sdk, {
|
|
1266
|
+
...input,
|
|
1267
|
+
nextAmountSat: input.nextAmountSat,
|
|
1268
|
+
maxFeeSat: input.maxFeeSat,
|
|
1269
|
+
nextOutputHash: input.nextOutputHash,
|
|
1270
|
+
});
|
|
1271
|
+
return { mode, settlement, ...result };
|
|
1272
|
+
}
|
|
1273
|
+
if (mode === "script-bound") {
|
|
1274
|
+
const result = await inspectBondScriptBoundMachineRollover(sdk, {
|
|
1275
|
+
...input,
|
|
1276
|
+
nextAmountSat: input.nextAmountSat,
|
|
1277
|
+
maxFeeSat: input.maxFeeSat,
|
|
1278
|
+
});
|
|
1279
|
+
return { mode, settlement, ...result };
|
|
1280
|
+
}
|
|
1281
|
+
const result = await inspectBondMachineRollover(sdk, input);
|
|
1282
|
+
return { mode, settlement, ...result };
|
|
1283
|
+
}
|
|
1284
|
+
async function executeRedemption(sdk, input) {
|
|
1285
|
+
const settlement = await buildBondSettlementPayload(sdk, {
|
|
1286
|
+
definitionPath: input.definitionPath,
|
|
1287
|
+
definitionValue: input.definitionValue,
|
|
1288
|
+
previousIssuancePath: input.previousIssuancePath,
|
|
1289
|
+
previousIssuanceValue: input.previousIssuanceValue,
|
|
1290
|
+
nextIssuancePath: input.nextIssuancePath,
|
|
1291
|
+
nextIssuanceValue: input.nextIssuanceValue,
|
|
1292
|
+
nextStateSimfPath: input.nextStateSimfPath,
|
|
1293
|
+
nextAmountSat: input.nextAmountSat ?? 1900,
|
|
1294
|
+
maxFeeSat: input.maxFeeSat,
|
|
1295
|
+
nextOutputHash: input.nextOutputHash,
|
|
1296
|
+
outputForm: input.outputForm,
|
|
1297
|
+
rawOutput: input.rawOutput,
|
|
1298
|
+
outputBindingMode: input.outputBindingMode,
|
|
1299
|
+
});
|
|
1300
|
+
const mode = resolveRedemptionBindingMode(settlement);
|
|
1301
|
+
if (mode === "descriptor-bound") {
|
|
1302
|
+
const result = await executeBondDescriptorBoundMachineRollover(sdk, {
|
|
1303
|
+
...input,
|
|
1304
|
+
nextAmountSat: input.nextAmountSat,
|
|
1305
|
+
maxFeeSat: input.maxFeeSat,
|
|
1306
|
+
nextOutputHash: input.nextOutputHash,
|
|
1307
|
+
});
|
|
1308
|
+
return { mode, settlement, ...result };
|
|
1309
|
+
}
|
|
1310
|
+
if (mode === "script-bound") {
|
|
1311
|
+
const result = await executeBondScriptBoundMachineRollover(sdk, {
|
|
1312
|
+
...input,
|
|
1313
|
+
nextAmountSat: input.nextAmountSat,
|
|
1314
|
+
maxFeeSat: input.maxFeeSat,
|
|
1315
|
+
});
|
|
1316
|
+
return { mode, settlement, ...result };
|
|
1317
|
+
}
|
|
1318
|
+
const result = await executeBondMachineRollover(sdk, input);
|
|
1319
|
+
return { mode, settlement, ...result };
|
|
1320
|
+
}
|
|
1321
|
+
async function verifyRedemption(sdk, input) {
|
|
1322
|
+
const settlement = await buildBondSettlementPayload(sdk, {
|
|
1323
|
+
definitionPath: input.definitionPath,
|
|
1324
|
+
definitionValue: input.definitionValue,
|
|
1325
|
+
previousIssuancePath: input.previousIssuancePath,
|
|
1326
|
+
previousIssuanceValue: input.previousIssuanceValue,
|
|
1327
|
+
nextIssuancePath: input.nextIssuancePath,
|
|
1328
|
+
nextIssuanceValue: input.nextIssuanceValue,
|
|
1329
|
+
nextStateSimfPath: input.nextStateSimfPath,
|
|
1330
|
+
nextAmountSat: input.nextAmountSat ?? 1900,
|
|
1331
|
+
maxFeeSat: input.maxFeeSat,
|
|
1332
|
+
nextOutputHash: input.nextOutputHash,
|
|
1333
|
+
outputForm: input.outputForm,
|
|
1334
|
+
rawOutput: input.rawOutput,
|
|
1335
|
+
outputBindingMode: input.outputBindingMode,
|
|
1336
|
+
});
|
|
1337
|
+
const mode = resolveRedemptionBindingMode(settlement);
|
|
1338
|
+
if (mode === "descriptor-bound") {
|
|
1339
|
+
const result = await verifyBondDescriptorBoundSettlementMachineArtifact(sdk, {
|
|
1340
|
+
...input,
|
|
1341
|
+
nextAmountSat: input.nextAmountSat,
|
|
1342
|
+
maxFeeSat: input.maxFeeSat,
|
|
1343
|
+
nextOutputHash: input.nextOutputHash,
|
|
1344
|
+
outputForm: input.outputForm,
|
|
1345
|
+
});
|
|
1346
|
+
return { mode, settlement, ...result };
|
|
1347
|
+
}
|
|
1348
|
+
if (mode === "script-bound") {
|
|
1349
|
+
const result = await verifyBondScriptBoundSettlementMachineArtifact(sdk, {
|
|
1350
|
+
...input,
|
|
1351
|
+
nextAmountSat: input.nextAmountSat,
|
|
1352
|
+
maxFeeSat: input.maxFeeSat,
|
|
1353
|
+
outputForm: input.outputForm,
|
|
1354
|
+
});
|
|
1355
|
+
return { mode, settlement, ...result };
|
|
1356
|
+
}
|
|
1357
|
+
const result = await verifyBondRedemptionMachineArtifact(sdk, {
|
|
1358
|
+
...input,
|
|
1359
|
+
outputForm: input.outputForm,
|
|
1360
|
+
});
|
|
1361
|
+
return { mode, settlement, ...result };
|
|
1362
|
+
}
|
|
1363
|
+
async function inspectClosing(sdk, input) {
|
|
1364
|
+
return inspectBondClosing(sdk, input);
|
|
1365
|
+
}
|
|
1366
|
+
async function executeClosing(sdk, input) {
|
|
1367
|
+
return executeBondClosing(sdk, input);
|
|
1368
|
+
}
|
|
1369
|
+
async function verifyClosing(sdk, input) {
|
|
1370
|
+
return verifyBondClosing(sdk, input);
|
|
1371
|
+
}
|
|
1372
|
+
async function exportEvidence(sdk, input) {
|
|
1373
|
+
return buildEvidenceBundle(sdk, input);
|
|
1374
|
+
}
|
|
496
1375
|
async function compileBondTransition(sdk, input) {
|
|
497
1376
|
const transitionPayload = await buildBondTransitionPayload(sdk, {
|
|
498
1377
|
definitionPath: input.definitionPath,
|
|
@@ -520,7 +1399,7 @@ async function compileBondTransition(sdk, input) {
|
|
|
520
1399
|
id: transitionPayload.next.issuanceId,
|
|
521
1400
|
...nextSource,
|
|
522
1401
|
});
|
|
523
|
-
const simfPath = input.simfPath ??
|
|
1402
|
+
const simfPath = input.simfPath ?? resolveBondDocsAsset("bond-redemption-transition.simf");
|
|
524
1403
|
const rawSource = await Promise.resolve().then(() => __importStar(require("node:fs/promises"))).then((fs) => fs.readFile(simfPath, "utf8"));
|
|
525
1404
|
const previousAnchor = detectPreviousStateAnchor(rawSource);
|
|
526
1405
|
if (!previousAnchor.sourceVerified) {
|
|
@@ -605,6 +1484,10 @@ async function verifyBondRedemptionMachineArtifact(sdk, input) {
|
|
|
605
1484
|
nextStateSimfPath: input.nextStateSimfPath,
|
|
606
1485
|
nextAmountSat: input.nextAmountSat ?? 1900,
|
|
607
1486
|
maxFeeSat: input.maxFeeSat ?? 100,
|
|
1487
|
+
nextOutputHash: input.nextOutputHash,
|
|
1488
|
+
outputForm: input.outputForm,
|
|
1489
|
+
rawOutput: input.rawOutput,
|
|
1490
|
+
outputBindingMode: input.outputBindingMode,
|
|
608
1491
|
});
|
|
609
1492
|
const templateVars = artifact.source.templateVars ?? {};
|
|
610
1493
|
const committed = {
|
|
@@ -619,7 +1502,10 @@ async function verifyBondRedemptionMachineArtifact(sdk, input) {
|
|
|
619
1502
|
nextOutstanding32: String(templateVars.NEXT_OUTSTANDING_32 ?? ""),
|
|
620
1503
|
nextRedeemed32: String(templateVars.NEXT_REDEEMED_32 ?? ""),
|
|
621
1504
|
nextContractAddressHash256: String(templateVars.NEXT_CONTRACT_ADDRESS_HASH_256 ?? ""),
|
|
1505
|
+
expectedNextOutputHash256: String(templateVars.EXPECTED_NEXT_OUTPUT_HASH_256 ?? ""),
|
|
1506
|
+
expectedNextOutputScriptHash256: String(templateVars.EXPECTED_NEXT_OUTPUT_SCRIPT_HASH_256 ?? ""),
|
|
622
1507
|
settlementDescriptorHash256: String(templateVars.SETTLEMENT_DESCRIPTOR_HASH ?? ""),
|
|
1508
|
+
expectedOutputDescriptorHash256: String(templateVars.EXPECTED_OUTPUT_DESCRIPTOR_HASH ?? ""),
|
|
623
1509
|
};
|
|
624
1510
|
const checks = {
|
|
625
1511
|
previousStateHashCommitted: committed.previousStateHash === expected.payload.previousStateHash,
|
|
@@ -633,7 +1519,14 @@ async function verifyBondRedemptionMachineArtifact(sdk, input) {
|
|
|
633
1519
|
&& committed.nextOutstanding32 === toUint32Hex(expected.payload.principal.nextOutstanding)
|
|
634
1520
|
&& committed.nextRedeemed32 === toUint32Hex(expected.payload.principal.nextRedeemed),
|
|
635
1521
|
nextContractAddressCommitted: committed.nextContractAddressHash256 === expectedNextContractAddressHash,
|
|
1522
|
+
nextOutputHashCommitted: !expectedSettlement.expectedOutputDescriptor?.nextOutputHash
|
|
1523
|
+
|| committed.expectedNextOutputHash256 === expectedSettlement.expectedOutputDescriptor.nextOutputHash,
|
|
1524
|
+
nextOutputScriptCommitted: !expectedSettlement.expectedOutputDescriptor?.nextOutputScriptHash
|
|
1525
|
+
|| committed.expectedNextOutputScriptHash256
|
|
1526
|
+
=== expectedSettlement.expectedOutputDescriptor.nextOutputScriptHash,
|
|
636
1527
|
settlementDescriptorCommitted: committed.settlementDescriptorHash256 === expectedSettlement.hash,
|
|
1528
|
+
expectedOutputDescriptorCommitted: !expectedSettlement.expectedOutputDescriptorHash
|
|
1529
|
+
|| committed.expectedOutputDescriptorHash256 === expectedSettlement.expectedOutputDescriptorHash,
|
|
637
1530
|
};
|
|
638
1531
|
const allChecks = Object.values(checks).every(Boolean);
|
|
639
1532
|
return {
|
|
@@ -647,6 +1540,16 @@ async function verifyBondRedemptionMachineArtifact(sdk, input) {
|
|
|
647
1540
|
},
|
|
648
1541
|
expectedSettlementDescriptor: expectedSettlement.descriptor,
|
|
649
1542
|
expectedSettlementDescriptorHash: expectedSettlement.hash,
|
|
1543
|
+
outputBindingMetadata: {
|
|
1544
|
+
requestedMode: expectedSettlement.expectedOutputDescriptor?.requestedOutputBindingMode
|
|
1545
|
+
?? expectedSettlement.descriptor.outputBindingMode
|
|
1546
|
+
?? "none",
|
|
1547
|
+
supportedForm: expectedSettlement.expectedOutputBindingSupportedForm,
|
|
1548
|
+
reasonCode: expectedSettlement.expectedOutputBindingReasonCode,
|
|
1549
|
+
autoDerived: expectedSettlement.expectedOutputBindingAutoDerived,
|
|
1550
|
+
fallbackReason: expectedSettlement.expectedOutputBindingFallbackReason,
|
|
1551
|
+
bindingInputs: expectedSettlement.expectedOutputBindingInputs,
|
|
1552
|
+
},
|
|
650
1553
|
expectedNextContractAddress,
|
|
651
1554
|
expectedNextContractAddressHash,
|
|
652
1555
|
committed,
|
|
@@ -705,8 +1608,12 @@ async function compileBondRedemptionMachine(sdk, input) {
|
|
|
705
1608
|
nextStateSimfPath: input.nextStateSimfPath,
|
|
706
1609
|
nextAmountSat: input.nextAmountSat ?? 1900,
|
|
707
1610
|
maxFeeSat: input.maxFeeSat ?? 100,
|
|
1611
|
+
nextOutputHash: input.nextOutputHash,
|
|
1612
|
+
outputForm: input.outputForm,
|
|
1613
|
+
rawOutput: input.rawOutput,
|
|
1614
|
+
outputBindingMode: input.outputBindingMode,
|
|
708
1615
|
});
|
|
709
|
-
const simfPath = input.simfPath ??
|
|
1616
|
+
const simfPath = input.simfPath ?? resolveBondDocsAsset("bond-redemption-state-machine.simf");
|
|
710
1617
|
const compiled = await sdk.compileFromFile({
|
|
711
1618
|
simfPath,
|
|
712
1619
|
templateVars: {
|
|
@@ -724,6 +1631,15 @@ async function compileBondRedemptionMachine(sdk, input) {
|
|
|
724
1631
|
NEXT_REDEEMED_32: toUint32Hex(transitionResult.payload.principal.nextRedeemed),
|
|
725
1632
|
NEXT_CONTRACT_ADDRESS_HASH_256: nextStateContractAddressHash,
|
|
726
1633
|
SETTLEMENT_DESCRIPTOR_HASH: settlementDescriptor.hash,
|
|
1634
|
+
...(input.expectedOutputDescriptorHash
|
|
1635
|
+
? { EXPECTED_OUTPUT_DESCRIPTOR_HASH: input.expectedOutputDescriptorHash }
|
|
1636
|
+
: {}),
|
|
1637
|
+
...(settlementDescriptor.expectedOutputDescriptor?.nextOutputHash
|
|
1638
|
+
? { EXPECTED_NEXT_OUTPUT_HASH_256: settlementDescriptor.expectedOutputDescriptor.nextOutputHash }
|
|
1639
|
+
: {}),
|
|
1640
|
+
...(settlementDescriptor.expectedOutputDescriptor?.nextOutputScriptHash
|
|
1641
|
+
? { EXPECTED_NEXT_OUTPUT_SCRIPT_HASH_256: settlementDescriptor.expectedOutputDescriptor.nextOutputScriptHash }
|
|
1642
|
+
: {}),
|
|
727
1643
|
},
|
|
728
1644
|
definition: {
|
|
729
1645
|
type: definitionDescriptor.definitionType,
|
|
@@ -768,13 +1684,147 @@ async function compileBondRedemptionMachine(sdk, input) {
|
|
|
768
1684
|
nextStateContractAddressHash,
|
|
769
1685
|
settlementDescriptor: settlementDescriptor.descriptor,
|
|
770
1686
|
settlementDescriptorHash: settlementDescriptor.hash,
|
|
1687
|
+
outputBindingMode: settlementDescriptor.descriptor.outputBindingMode ?? "none",
|
|
771
1688
|
},
|
|
772
1689
|
};
|
|
773
1690
|
}
|
|
774
|
-
async function
|
|
775
|
-
const
|
|
776
|
-
|
|
777
|
-
|
|
1691
|
+
async function compileBondScriptBoundSettlementMachine(sdk, input) {
|
|
1692
|
+
const settlement = await buildBondSettlementDescriptor(sdk, {
|
|
1693
|
+
definitionPath: input.definitionPath,
|
|
1694
|
+
definitionValue: input.definitionValue,
|
|
1695
|
+
previousIssuancePath: input.previousIssuancePath,
|
|
1696
|
+
previousIssuanceValue: input.previousIssuanceValue,
|
|
1697
|
+
nextIssuancePath: input.nextIssuancePath,
|
|
1698
|
+
nextIssuanceValue: input.nextIssuanceValue,
|
|
1699
|
+
nextStateSimfPath: input.nextStateSimfPath,
|
|
1700
|
+
nextAmountSat: input.nextAmountSat ?? 1900,
|
|
1701
|
+
maxFeeSat: input.maxFeeSat ?? 100,
|
|
1702
|
+
rawOutput: input.rawOutput,
|
|
1703
|
+
outputBindingMode: "script-bound",
|
|
1704
|
+
});
|
|
1705
|
+
const base = await compileBondRedemptionMachine(sdk, {
|
|
1706
|
+
...input,
|
|
1707
|
+
outputBindingMode: "script-bound",
|
|
1708
|
+
expectedOutputDescriptorHash: settlement.expectedOutputDescriptorHash,
|
|
1709
|
+
simfPath: input.simfPath ?? resolveBondDocsAsset("bond-script-bound-settlement-machine.simf"),
|
|
1710
|
+
});
|
|
1711
|
+
return {
|
|
1712
|
+
...base,
|
|
1713
|
+
expectedOutputDescriptor: settlement.expectedOutputDescriptor,
|
|
1714
|
+
expectedOutputDescriptorHash: settlement.expectedOutputDescriptorHash,
|
|
1715
|
+
outputBindingMode: "script-bound",
|
|
1716
|
+
};
|
|
1717
|
+
}
|
|
1718
|
+
async function verifyBondScriptBoundSettlementMachineArtifact(sdk, input) {
|
|
1719
|
+
const base = await verifyBondRedemptionMachineArtifact(sdk, {
|
|
1720
|
+
...input,
|
|
1721
|
+
outputBindingMode: "script-bound",
|
|
1722
|
+
});
|
|
1723
|
+
return {
|
|
1724
|
+
...base,
|
|
1725
|
+
outputBindingTrust: {
|
|
1726
|
+
mode: "script-bound",
|
|
1727
|
+
requestedMode: base.outputBindingMetadata.requestedMode,
|
|
1728
|
+
supportedForm: base.outputBindingMetadata.supportedForm,
|
|
1729
|
+
outputCountRuntimeBound: true,
|
|
1730
|
+
feeIndexRuntimeBound: true,
|
|
1731
|
+
settlementDescriptorCommitted: base.checks.settlementDescriptorCommitted,
|
|
1732
|
+
nextContractAddressCommitted: base.checks.nextContractAddressCommitted,
|
|
1733
|
+
nextOutputHashRuntimeBound: false,
|
|
1734
|
+
nextOutputScriptRuntimeBound: true,
|
|
1735
|
+
amountRuntimeBound: false,
|
|
1736
|
+
reasonCode: base.outputBindingMetadata.reasonCode,
|
|
1737
|
+
autoDerived: base.outputBindingMetadata.autoDerived,
|
|
1738
|
+
fallbackReason: base.outputBindingMetadata.fallbackReason,
|
|
1739
|
+
bindingInputs: base.outputBindingMetadata.bindingInputs,
|
|
1740
|
+
},
|
|
1741
|
+
};
|
|
1742
|
+
}
|
|
1743
|
+
async function compileBondDescriptorBoundSettlementMachine(sdk, input) {
|
|
1744
|
+
const settlement = await buildBondSettlementDescriptor(sdk, {
|
|
1745
|
+
definitionPath: input.definitionPath,
|
|
1746
|
+
definitionValue: input.definitionValue,
|
|
1747
|
+
previousIssuancePath: input.previousIssuancePath,
|
|
1748
|
+
previousIssuanceValue: input.previousIssuanceValue,
|
|
1749
|
+
nextIssuancePath: input.nextIssuancePath,
|
|
1750
|
+
nextIssuanceValue: input.nextIssuanceValue,
|
|
1751
|
+
nextStateSimfPath: input.nextStateSimfPath,
|
|
1752
|
+
nextAmountSat: input.nextAmountSat ?? 1900,
|
|
1753
|
+
maxFeeSat: input.maxFeeSat ?? 100,
|
|
1754
|
+
nextOutputHash: input.nextOutputHash,
|
|
1755
|
+
rawOutput: input.rawOutput,
|
|
1756
|
+
outputBindingMode: "descriptor-bound",
|
|
1757
|
+
});
|
|
1758
|
+
if (settlement.descriptor.outputBindingMode !== "descriptor-bound") {
|
|
1759
|
+
const fallback = await compileBondScriptBoundSettlementMachine(sdk, input);
|
|
1760
|
+
return {
|
|
1761
|
+
...fallback,
|
|
1762
|
+
requestedOutputBindingMode: "descriptor-bound",
|
|
1763
|
+
outputBindingMode: fallback.outputBindingMode,
|
|
1764
|
+
};
|
|
1765
|
+
}
|
|
1766
|
+
const base = await compileBondRedemptionMachine(sdk, {
|
|
1767
|
+
...input,
|
|
1768
|
+
nextOutputHash: settlement.expectedOutputDescriptor?.nextOutputHash,
|
|
1769
|
+
outputBindingMode: "descriptor-bound",
|
|
1770
|
+
expectedOutputDescriptorHash: settlement.expectedOutputDescriptorHash,
|
|
1771
|
+
simfPath: input.simfPath ?? resolveBondDocsAsset("bond-descriptor-bound-settlement-machine.simf"),
|
|
1772
|
+
});
|
|
1773
|
+
return {
|
|
1774
|
+
...base,
|
|
1775
|
+
expectedOutputDescriptor: settlement.expectedOutputDescriptor,
|
|
1776
|
+
expectedOutputDescriptorHash: settlement.expectedOutputDescriptorHash,
|
|
1777
|
+
requestedOutputBindingMode: "descriptor-bound",
|
|
1778
|
+
outputBindingMode: "descriptor-bound",
|
|
1779
|
+
};
|
|
1780
|
+
}
|
|
1781
|
+
async function verifyBondDescriptorBoundSettlementMachineArtifact(sdk, input) {
|
|
1782
|
+
const base = await verifyBondRedemptionMachineArtifact(sdk, {
|
|
1783
|
+
...input,
|
|
1784
|
+
outputBindingMode: "descriptor-bound",
|
|
1785
|
+
});
|
|
1786
|
+
const mode = base.expectedSettlementDescriptor.outputBindingMode === "descriptor-bound" && base.checks.nextOutputHashCommitted
|
|
1787
|
+
? "descriptor-bound"
|
|
1788
|
+
: "script-bound";
|
|
1789
|
+
return {
|
|
1790
|
+
...base,
|
|
1791
|
+
outputBindingTrust: {
|
|
1792
|
+
mode,
|
|
1793
|
+
requestedMode: base.outputBindingMetadata.requestedMode,
|
|
1794
|
+
supportedForm: base.outputBindingMetadata.supportedForm,
|
|
1795
|
+
outputCountRuntimeBound: true,
|
|
1796
|
+
feeIndexRuntimeBound: true,
|
|
1797
|
+
settlementDescriptorCommitted: base.checks.settlementDescriptorCommitted,
|
|
1798
|
+
nextContractAddressCommitted: base.checks.nextContractAddressCommitted,
|
|
1799
|
+
nextOutputHashRuntimeBound: mode === "descriptor-bound",
|
|
1800
|
+
nextOutputScriptRuntimeBound: mode !== "descriptor-bound",
|
|
1801
|
+
amountRuntimeBound: false,
|
|
1802
|
+
reasonCode: base.outputBindingMetadata.reasonCode,
|
|
1803
|
+
autoDerived: base.outputBindingMetadata.autoDerived,
|
|
1804
|
+
fallbackReason: base.outputBindingMetadata.fallbackReason,
|
|
1805
|
+
bindingInputs: base.outputBindingMetadata.bindingInputs,
|
|
1806
|
+
},
|
|
1807
|
+
};
|
|
1808
|
+
}
|
|
1809
|
+
async function compileBondClosingMachine(sdk, input) {
|
|
1810
|
+
const closing = await buildBondClosing(sdk, input);
|
|
1811
|
+
const result = await defineBond(sdk, {
|
|
1812
|
+
definitionValue: closing.definition,
|
|
1813
|
+
issuanceValue: closing.closed,
|
|
1814
|
+
simfPath: input.simfPath ?? resolveBondDocsAsset("bond-issuance-anchor.simf"),
|
|
1815
|
+
artifactPath: input.artifactPath,
|
|
1816
|
+
});
|
|
1817
|
+
return {
|
|
1818
|
+
compiled: result,
|
|
1819
|
+
closing: closing.closing,
|
|
1820
|
+
closingHash: closing.closingHash,
|
|
1821
|
+
closedState: closing.closed,
|
|
1822
|
+
};
|
|
1823
|
+
}
|
|
1824
|
+
async function buildBondRedemption(sdk, input) {
|
|
1825
|
+
const definitionSource = resolveValueOrPath({
|
|
1826
|
+
pathValue: input.definitionPath,
|
|
1827
|
+
objectValue: input.definitionValue,
|
|
778
1828
|
});
|
|
779
1829
|
const previousSource = resolveValueOrPath({
|
|
780
1830
|
pathValue: input.previousIssuancePath,
|
|
@@ -931,6 +1981,102 @@ async function buildBondMachineRolloverPlan(sdk, input) {
|
|
|
931
1981
|
transitionPayload: machineCompiled.payload,
|
|
932
1982
|
};
|
|
933
1983
|
}
|
|
1984
|
+
async function buildBondScriptBoundMachineRolloverPlan(sdk, input) {
|
|
1985
|
+
const currentArtifact = input.currentArtifact
|
|
1986
|
+
?? (input.currentArtifactPath ? (await sdk.loadArtifact(input.currentArtifactPath)).artifact : undefined);
|
|
1987
|
+
if (!currentArtifact) {
|
|
1988
|
+
throw new Error("currentArtifactPath or currentArtifact is required");
|
|
1989
|
+
}
|
|
1990
|
+
const currentVerification = await verifyBond(sdk, {
|
|
1991
|
+
artifact: currentArtifact,
|
|
1992
|
+
definitionPath: input.definitionPath,
|
|
1993
|
+
definitionValue: input.definitionValue,
|
|
1994
|
+
issuancePath: input.previousIssuancePath,
|
|
1995
|
+
issuanceValue: input.previousIssuanceValue,
|
|
1996
|
+
});
|
|
1997
|
+
const machineCompiled = await compileBondScriptBoundSettlementMachine(sdk, {
|
|
1998
|
+
definitionPath: input.definitionPath,
|
|
1999
|
+
definitionValue: input.definitionValue,
|
|
2000
|
+
previousIssuancePath: input.previousIssuancePath,
|
|
2001
|
+
previousIssuanceValue: input.previousIssuanceValue,
|
|
2002
|
+
nextIssuancePath: input.nextIssuancePath,
|
|
2003
|
+
nextIssuanceValue: input.nextIssuanceValue,
|
|
2004
|
+
nextStateSimfPath: input.nextStateSimfPath,
|
|
2005
|
+
nextAmountSat: input.nextAmountSat,
|
|
2006
|
+
maxFeeSat: input.maxFeeSat,
|
|
2007
|
+
simfPath: input.machineSimfPath,
|
|
2008
|
+
artifactPath: input.machineArtifactPath,
|
|
2009
|
+
});
|
|
2010
|
+
const machineVerification = await verifyBondScriptBoundSettlementMachineArtifact(sdk, {
|
|
2011
|
+
artifact: machineCompiled.compiled.artifact,
|
|
2012
|
+
definitionPath: input.definitionPath,
|
|
2013
|
+
definitionValue: input.definitionValue,
|
|
2014
|
+
previousIssuancePath: input.previousIssuancePath,
|
|
2015
|
+
previousIssuanceValue: input.previousIssuanceValue,
|
|
2016
|
+
nextIssuancePath: input.nextIssuancePath,
|
|
2017
|
+
nextIssuanceValue: input.nextIssuanceValue,
|
|
2018
|
+
nextStateSimfPath: input.nextStateSimfPath,
|
|
2019
|
+
nextAmountSat: input.nextAmountSat,
|
|
2020
|
+
maxFeeSat: input.maxFeeSat,
|
|
2021
|
+
});
|
|
2022
|
+
return {
|
|
2023
|
+
currentArtifact,
|
|
2024
|
+
currentVerification,
|
|
2025
|
+
machineCompiled,
|
|
2026
|
+
machineVerification,
|
|
2027
|
+
nextContractAddress: machineCompiled.compiled.deployment().contractAddress,
|
|
2028
|
+
transitionPayload: machineCompiled.payload,
|
|
2029
|
+
};
|
|
2030
|
+
}
|
|
2031
|
+
async function buildBondDescriptorBoundMachineRolloverPlan(sdk, input) {
|
|
2032
|
+
const currentArtifact = input.currentArtifact
|
|
2033
|
+
?? (input.currentArtifactPath ? (await sdk.loadArtifact(input.currentArtifactPath)).artifact : undefined);
|
|
2034
|
+
if (!currentArtifact) {
|
|
2035
|
+
throw new Error("currentArtifactPath or currentArtifact is required");
|
|
2036
|
+
}
|
|
2037
|
+
const currentVerification = await verifyBond(sdk, {
|
|
2038
|
+
artifact: currentArtifact,
|
|
2039
|
+
definitionPath: input.definitionPath,
|
|
2040
|
+
definitionValue: input.definitionValue,
|
|
2041
|
+
issuancePath: input.previousIssuancePath,
|
|
2042
|
+
issuanceValue: input.previousIssuanceValue,
|
|
2043
|
+
});
|
|
2044
|
+
const machineCompiled = await compileBondDescriptorBoundSettlementMachine(sdk, {
|
|
2045
|
+
definitionPath: input.definitionPath,
|
|
2046
|
+
definitionValue: input.definitionValue,
|
|
2047
|
+
previousIssuancePath: input.previousIssuancePath,
|
|
2048
|
+
previousIssuanceValue: input.previousIssuanceValue,
|
|
2049
|
+
nextIssuancePath: input.nextIssuancePath,
|
|
2050
|
+
nextIssuanceValue: input.nextIssuanceValue,
|
|
2051
|
+
nextStateSimfPath: input.nextStateSimfPath,
|
|
2052
|
+
nextAmountSat: input.nextAmountSat,
|
|
2053
|
+
maxFeeSat: input.maxFeeSat,
|
|
2054
|
+
nextOutputHash: input.nextOutputHash,
|
|
2055
|
+
simfPath: input.machineSimfPath,
|
|
2056
|
+
artifactPath: input.machineArtifactPath,
|
|
2057
|
+
});
|
|
2058
|
+
const machineVerification = await verifyBondDescriptorBoundSettlementMachineArtifact(sdk, {
|
|
2059
|
+
artifact: machineCompiled.compiled.artifact,
|
|
2060
|
+
definitionPath: input.definitionPath,
|
|
2061
|
+
definitionValue: input.definitionValue,
|
|
2062
|
+
previousIssuancePath: input.previousIssuancePath,
|
|
2063
|
+
previousIssuanceValue: input.previousIssuanceValue,
|
|
2064
|
+
nextIssuancePath: input.nextIssuancePath,
|
|
2065
|
+
nextIssuanceValue: input.nextIssuanceValue,
|
|
2066
|
+
nextStateSimfPath: input.nextStateSimfPath,
|
|
2067
|
+
nextAmountSat: input.nextAmountSat,
|
|
2068
|
+
maxFeeSat: input.maxFeeSat,
|
|
2069
|
+
nextOutputHash: input.nextOutputHash,
|
|
2070
|
+
});
|
|
2071
|
+
return {
|
|
2072
|
+
currentArtifact,
|
|
2073
|
+
currentVerification,
|
|
2074
|
+
machineCompiled,
|
|
2075
|
+
machineVerification,
|
|
2076
|
+
nextContractAddress: machineCompiled.compiled.deployment().contractAddress,
|
|
2077
|
+
transitionPayload: machineCompiled.payload,
|
|
2078
|
+
};
|
|
2079
|
+
}
|
|
934
2080
|
async function buildBondMachineSettlementPlan(sdk, input) {
|
|
935
2081
|
const currentMachineArtifact = input.currentMachineArtifact
|
|
936
2082
|
?? (input.currentMachineArtifactPath ? (await sdk.loadArtifact(input.currentMachineArtifactPath)).artifact : undefined);
|
|
@@ -965,6 +2111,79 @@ async function buildBondMachineSettlementPlan(sdk, input) {
|
|
|
965
2111
|
nextContractAddressMatchesMachineCommitment: nextCompiled.deployment().contractAddress === machineVerification.expectedNextContractAddress,
|
|
966
2112
|
};
|
|
967
2113
|
}
|
|
2114
|
+
async function buildBondScriptBoundMachineSettlementPlan(sdk, input) {
|
|
2115
|
+
const currentMachineArtifact = input.currentMachineArtifact
|
|
2116
|
+
?? (input.currentMachineArtifactPath ? (await sdk.loadArtifact(input.currentMachineArtifactPath)).artifact : undefined);
|
|
2117
|
+
if (!currentMachineArtifact) {
|
|
2118
|
+
throw new Error("currentMachineArtifactPath or currentMachineArtifact is required");
|
|
2119
|
+
}
|
|
2120
|
+
const machineVerification = await verifyBondScriptBoundSettlementMachineArtifact(sdk, {
|
|
2121
|
+
artifact: currentMachineArtifact,
|
|
2122
|
+
definitionPath: input.definitionPath,
|
|
2123
|
+
definitionValue: input.definitionValue,
|
|
2124
|
+
previousIssuancePath: input.previousIssuancePath,
|
|
2125
|
+
previousIssuanceValue: input.previousIssuanceValue,
|
|
2126
|
+
nextIssuancePath: input.nextIssuancePath,
|
|
2127
|
+
nextIssuanceValue: input.nextIssuanceValue,
|
|
2128
|
+
nextStateSimfPath: input.nextSimfPath,
|
|
2129
|
+
nextAmountSat: input.nextAmountSat,
|
|
2130
|
+
maxFeeSat: input.maxFeeSat,
|
|
2131
|
+
});
|
|
2132
|
+
const definitionValue = (0, bondValidation_1.validateBondDefinition)(JSON.parse(machineVerification.definition.definition.canonicalJson));
|
|
2133
|
+
const nextStateValue = (0, bondValidation_1.validateBondIssuanceState)(JSON.parse(machineVerification.issuance.state.canonicalJson));
|
|
2134
|
+
const nextCompiled = await defineBond(sdk, {
|
|
2135
|
+
definitionPath: input.definitionPath,
|
|
2136
|
+
definitionValue,
|
|
2137
|
+
issuanceValue: nextStateValue,
|
|
2138
|
+
simfPath: input.nextSimfPath,
|
|
2139
|
+
artifactPath: input.nextArtifactPath,
|
|
2140
|
+
});
|
|
2141
|
+
return {
|
|
2142
|
+
currentMachineArtifact,
|
|
2143
|
+
machineVerification,
|
|
2144
|
+
nextCompiled,
|
|
2145
|
+
nextContractAddress: nextCompiled.deployment().contractAddress,
|
|
2146
|
+
transitionPayload: machineVerification.expectedPayload,
|
|
2147
|
+
nextContractAddressMatchesMachineCommitment: nextCompiled.deployment().contractAddress === machineVerification.expectedNextContractAddress,
|
|
2148
|
+
};
|
|
2149
|
+
}
|
|
2150
|
+
async function buildBondDescriptorBoundMachineSettlementPlan(sdk, input) {
|
|
2151
|
+
const currentMachineArtifact = input.currentMachineArtifact
|
|
2152
|
+
?? (input.currentMachineArtifactPath ? (await sdk.loadArtifact(input.currentMachineArtifactPath)).artifact : undefined);
|
|
2153
|
+
if (!currentMachineArtifact) {
|
|
2154
|
+
throw new Error("currentMachineArtifactPath or currentMachineArtifact is required");
|
|
2155
|
+
}
|
|
2156
|
+
const machineVerification = await verifyBondDescriptorBoundSettlementMachineArtifact(sdk, {
|
|
2157
|
+
artifact: currentMachineArtifact,
|
|
2158
|
+
definitionPath: input.definitionPath,
|
|
2159
|
+
definitionValue: input.definitionValue,
|
|
2160
|
+
previousIssuancePath: input.previousIssuancePath,
|
|
2161
|
+
previousIssuanceValue: input.previousIssuanceValue,
|
|
2162
|
+
nextIssuancePath: input.nextIssuancePath,
|
|
2163
|
+
nextIssuanceValue: input.nextIssuanceValue,
|
|
2164
|
+
nextStateSimfPath: input.nextSimfPath,
|
|
2165
|
+
nextAmountSat: input.nextAmountSat,
|
|
2166
|
+
maxFeeSat: input.maxFeeSat,
|
|
2167
|
+
nextOutputHash: input.nextOutputHash,
|
|
2168
|
+
});
|
|
2169
|
+
const definitionValue = (0, bondValidation_1.validateBondDefinition)(JSON.parse(machineVerification.definition.definition.canonicalJson));
|
|
2170
|
+
const nextStateValue = (0, bondValidation_1.validateBondIssuanceState)(JSON.parse(machineVerification.issuance.state.canonicalJson));
|
|
2171
|
+
const nextCompiled = await defineBond(sdk, {
|
|
2172
|
+
definitionPath: input.definitionPath,
|
|
2173
|
+
definitionValue,
|
|
2174
|
+
issuanceValue: nextStateValue,
|
|
2175
|
+
simfPath: input.nextSimfPath,
|
|
2176
|
+
artifactPath: input.nextArtifactPath,
|
|
2177
|
+
});
|
|
2178
|
+
return {
|
|
2179
|
+
currentMachineArtifact,
|
|
2180
|
+
machineVerification,
|
|
2181
|
+
nextCompiled,
|
|
2182
|
+
nextContractAddress: nextCompiled.deployment().contractAddress,
|
|
2183
|
+
transitionPayload: machineVerification.expectedPayload,
|
|
2184
|
+
nextContractAddressMatchesMachineCommitment: nextCompiled.deployment().contractAddress === machineVerification.expectedNextContractAddress,
|
|
2185
|
+
};
|
|
2186
|
+
}
|
|
968
2187
|
async function inspectBondStateRollover(sdk, input) {
|
|
969
2188
|
const plan = await buildBondRolloverPlan(sdk, input);
|
|
970
2189
|
const contract = sdk.fromArtifact(plan.currentArtifact);
|
|
@@ -989,6 +2208,30 @@ async function inspectBondMachineRollover(sdk, input) {
|
|
|
989
2208
|
});
|
|
990
2209
|
return { plan, inspect };
|
|
991
2210
|
}
|
|
2211
|
+
async function inspectBondScriptBoundMachineRollover(sdk, input) {
|
|
2212
|
+
const plan = await buildBondScriptBoundMachineRolloverPlan(sdk, input);
|
|
2213
|
+
const contract = sdk.fromArtifact(plan.currentArtifact);
|
|
2214
|
+
const inspect = await contract.inspectCall({
|
|
2215
|
+
wallet: input.wallet,
|
|
2216
|
+
toAddress: plan.nextContractAddress,
|
|
2217
|
+
signer: input.signer,
|
|
2218
|
+
feeSat: input.feeSat,
|
|
2219
|
+
utxoPolicy: input.utxoPolicy,
|
|
2220
|
+
});
|
|
2221
|
+
return { plan, inspect };
|
|
2222
|
+
}
|
|
2223
|
+
async function inspectBondDescriptorBoundMachineRollover(sdk, input) {
|
|
2224
|
+
const plan = await buildBondDescriptorBoundMachineRolloverPlan(sdk, input);
|
|
2225
|
+
const contract = sdk.fromArtifact(plan.currentArtifact);
|
|
2226
|
+
const inspect = await contract.inspectCall({
|
|
2227
|
+
wallet: input.wallet,
|
|
2228
|
+
toAddress: plan.nextContractAddress,
|
|
2229
|
+
signer: input.signer,
|
|
2230
|
+
feeSat: input.feeSat,
|
|
2231
|
+
utxoPolicy: input.utxoPolicy,
|
|
2232
|
+
});
|
|
2233
|
+
return { plan, inspect };
|
|
2234
|
+
}
|
|
992
2235
|
async function inspectBondMachineSettlement(sdk, input) {
|
|
993
2236
|
const plan = await buildBondMachineSettlementPlan(sdk, input);
|
|
994
2237
|
const contract = sdk.fromArtifact(plan.currentMachineArtifact);
|
|
@@ -1001,6 +2244,76 @@ async function inspectBondMachineSettlement(sdk, input) {
|
|
|
1001
2244
|
});
|
|
1002
2245
|
return { plan, inspect };
|
|
1003
2246
|
}
|
|
2247
|
+
async function inspectBondScriptBoundMachineSettlement(sdk, input) {
|
|
2248
|
+
const plan = await buildBondScriptBoundMachineSettlementPlan(sdk, input);
|
|
2249
|
+
const contract = sdk.fromArtifact(plan.currentMachineArtifact);
|
|
2250
|
+
const inspect = await contract.inspectCall({
|
|
2251
|
+
wallet: input.wallet,
|
|
2252
|
+
toAddress: plan.nextContractAddress,
|
|
2253
|
+
signer: input.signer,
|
|
2254
|
+
feeSat: input.feeSat,
|
|
2255
|
+
utxoPolicy: input.utxoPolicy,
|
|
2256
|
+
});
|
|
2257
|
+
return { plan, inspect };
|
|
2258
|
+
}
|
|
2259
|
+
async function inspectBondDescriptorBoundMachineSettlement(sdk, input) {
|
|
2260
|
+
const plan = await buildBondDescriptorBoundMachineSettlementPlan(sdk, input);
|
|
2261
|
+
const contract = sdk.fromArtifact(plan.currentMachineArtifact);
|
|
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 buildBondClosingPlan(sdk, input) {
|
|
2272
|
+
const currentArtifact = input.currentArtifact
|
|
2273
|
+
?? (input.currentArtifactPath ? (await sdk.loadArtifact(input.currentArtifactPath)).artifact : undefined);
|
|
2274
|
+
if (!currentArtifact) {
|
|
2275
|
+
throw new Error("currentArtifactPath or currentArtifact is required");
|
|
2276
|
+
}
|
|
2277
|
+
const currentVerification = await verifyBond(sdk, {
|
|
2278
|
+
artifact: currentArtifact,
|
|
2279
|
+
definitionPath: input.definitionPath,
|
|
2280
|
+
definitionValue: input.definitionValue,
|
|
2281
|
+
issuancePath: input.redeemedIssuancePath,
|
|
2282
|
+
issuanceValue: input.redeemedIssuanceValue,
|
|
2283
|
+
});
|
|
2284
|
+
const closingCompiled = await compileBondClosingMachine(sdk, {
|
|
2285
|
+
definitionPath: input.definitionPath,
|
|
2286
|
+
definitionValue: input.definitionValue,
|
|
2287
|
+
redeemedIssuancePath: input.redeemedIssuancePath,
|
|
2288
|
+
redeemedIssuanceValue: input.redeemedIssuanceValue,
|
|
2289
|
+
settlementDescriptorPath: input.settlementDescriptorPath,
|
|
2290
|
+
settlementDescriptorValue: input.settlementDescriptorValue,
|
|
2291
|
+
closedAt: input.closedAt,
|
|
2292
|
+
closingReason: input.closingReason,
|
|
2293
|
+
simfPath: input.closedIssuanceSimfPath,
|
|
2294
|
+
artifactPath: input.closingArtifactPath,
|
|
2295
|
+
});
|
|
2296
|
+
const closingVerification = await verifyBondClosing(sdk, {
|
|
2297
|
+
definitionPath: input.definitionPath,
|
|
2298
|
+
definitionValue: input.definitionValue,
|
|
2299
|
+
redeemedIssuancePath: input.redeemedIssuancePath,
|
|
2300
|
+
redeemedIssuanceValue: input.redeemedIssuanceValue,
|
|
2301
|
+
closedIssuanceValue: closingCompiled.closedState,
|
|
2302
|
+
settlementDescriptorPath: input.settlementDescriptorPath,
|
|
2303
|
+
settlementDescriptorValue: input.settlementDescriptorValue,
|
|
2304
|
+
closingDescriptorValue: closingCompiled.closing,
|
|
2305
|
+
});
|
|
2306
|
+
return {
|
|
2307
|
+
currentArtifact,
|
|
2308
|
+
currentVerification,
|
|
2309
|
+
closingCompiled,
|
|
2310
|
+
closingVerification,
|
|
2311
|
+
nextContractAddress: closingCompiled.compiled.deployment().contractAddress,
|
|
2312
|
+
closingDescriptor: closingCompiled.closing,
|
|
2313
|
+
closingHash: closingCompiled.closingHash,
|
|
2314
|
+
closedState: closingCompiled.closedState,
|
|
2315
|
+
};
|
|
2316
|
+
}
|
|
1004
2317
|
async function executeBondStateRollover(sdk, input) {
|
|
1005
2318
|
const plan = await buildBondRolloverPlan(sdk, input);
|
|
1006
2319
|
const contract = sdk.fromArtifact(plan.currentArtifact);
|
|
@@ -1027,6 +2340,32 @@ async function executeBondMachineRollover(sdk, input) {
|
|
|
1027
2340
|
});
|
|
1028
2341
|
return { plan, execution };
|
|
1029
2342
|
}
|
|
2343
|
+
async function executeBondScriptBoundMachineRollover(sdk, input) {
|
|
2344
|
+
const plan = await buildBondScriptBoundMachineRolloverPlan(sdk, input);
|
|
2345
|
+
const contract = sdk.fromArtifact(plan.currentArtifact);
|
|
2346
|
+
const execution = await contract.execute({
|
|
2347
|
+
wallet: input.wallet,
|
|
2348
|
+
toAddress: plan.nextContractAddress,
|
|
2349
|
+
signer: input.signer,
|
|
2350
|
+
feeSat: input.feeSat,
|
|
2351
|
+
utxoPolicy: input.utxoPolicy,
|
|
2352
|
+
broadcast: input.broadcast,
|
|
2353
|
+
});
|
|
2354
|
+
return { plan, execution };
|
|
2355
|
+
}
|
|
2356
|
+
async function executeBondDescriptorBoundMachineRollover(sdk, input) {
|
|
2357
|
+
const plan = await buildBondDescriptorBoundMachineRolloverPlan(sdk, input);
|
|
2358
|
+
const contract = sdk.fromArtifact(plan.currentArtifact);
|
|
2359
|
+
const execution = await contract.execute({
|
|
2360
|
+
wallet: input.wallet,
|
|
2361
|
+
toAddress: plan.nextContractAddress,
|
|
2362
|
+
signer: input.signer,
|
|
2363
|
+
feeSat: input.feeSat,
|
|
2364
|
+
utxoPolicy: input.utxoPolicy,
|
|
2365
|
+
broadcast: input.broadcast,
|
|
2366
|
+
});
|
|
2367
|
+
return { plan, execution };
|
|
2368
|
+
}
|
|
1030
2369
|
async function executeBondMachineSettlement(sdk, input) {
|
|
1031
2370
|
const plan = await buildBondMachineSettlementPlan(sdk, input);
|
|
1032
2371
|
const contract = sdk.fromArtifact(plan.currentMachineArtifact);
|
|
@@ -1040,3 +2379,54 @@ async function executeBondMachineSettlement(sdk, input) {
|
|
|
1040
2379
|
});
|
|
1041
2380
|
return { plan, execution };
|
|
1042
2381
|
}
|
|
2382
|
+
async function executeBondScriptBoundMachineSettlement(sdk, input) {
|
|
2383
|
+
const plan = await buildBondScriptBoundMachineSettlementPlan(sdk, input);
|
|
2384
|
+
const contract = sdk.fromArtifact(plan.currentMachineArtifact);
|
|
2385
|
+
const execution = await contract.execute({
|
|
2386
|
+
wallet: input.wallet,
|
|
2387
|
+
toAddress: plan.nextContractAddress,
|
|
2388
|
+
signer: input.signer,
|
|
2389
|
+
feeSat: input.feeSat,
|
|
2390
|
+
utxoPolicy: input.utxoPolicy,
|
|
2391
|
+
broadcast: input.broadcast,
|
|
2392
|
+
});
|
|
2393
|
+
return { plan, execution };
|
|
2394
|
+
}
|
|
2395
|
+
async function executeBondDescriptorBoundMachineSettlement(sdk, input) {
|
|
2396
|
+
const plan = await buildBondDescriptorBoundMachineSettlementPlan(sdk, input);
|
|
2397
|
+
const contract = sdk.fromArtifact(plan.currentMachineArtifact);
|
|
2398
|
+
const execution = await contract.execute({
|
|
2399
|
+
wallet: input.wallet,
|
|
2400
|
+
toAddress: plan.nextContractAddress,
|
|
2401
|
+
signer: input.signer,
|
|
2402
|
+
feeSat: input.feeSat,
|
|
2403
|
+
utxoPolicy: input.utxoPolicy,
|
|
2404
|
+
broadcast: input.broadcast,
|
|
2405
|
+
});
|
|
2406
|
+
return { plan, execution };
|
|
2407
|
+
}
|
|
2408
|
+
async function inspectBondClosing(sdk, input) {
|
|
2409
|
+
const plan = await buildBondClosingPlan(sdk, input);
|
|
2410
|
+
const contract = sdk.fromArtifact(plan.currentArtifact);
|
|
2411
|
+
const inspect = await contract.inspectCall({
|
|
2412
|
+
wallet: input.wallet,
|
|
2413
|
+
toAddress: plan.nextContractAddress,
|
|
2414
|
+
signer: input.signer,
|
|
2415
|
+
feeSat: input.feeSat,
|
|
2416
|
+
utxoPolicy: input.utxoPolicy,
|
|
2417
|
+
});
|
|
2418
|
+
return { plan, inspect };
|
|
2419
|
+
}
|
|
2420
|
+
async function executeBondClosing(sdk, input) {
|
|
2421
|
+
const plan = await buildBondClosingPlan(sdk, input);
|
|
2422
|
+
const contract = sdk.fromArtifact(plan.currentArtifact);
|
|
2423
|
+
const execution = await contract.execute({
|
|
2424
|
+
wallet: input.wallet,
|
|
2425
|
+
toAddress: plan.nextContractAddress,
|
|
2426
|
+
signer: input.signer,
|
|
2427
|
+
feeSat: input.feeSat,
|
|
2428
|
+
utxoPolicy: input.utxoPolicy,
|
|
2429
|
+
broadcast: input.broadcast,
|
|
2430
|
+
});
|
|
2431
|
+
return { plan, execution };
|
|
2432
|
+
}
|