@hazbase/simplicity 0.0.4 → 0.0.5
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 -0
- package/dist/cli.js +297 -0
- package/dist/client/SimplicityClient.d.ts +267 -2
- package/dist/client/SimplicityClient.js +20 -0
- package/dist/core/types.d.ts +34 -1
- package/dist/domain/bond.d.ts +1993 -1
- package/dist/domain/bond.js +914 -0
- package/dist/domain/bondSettlementValidation.d.ts +18 -0
- package/dist/domain/bondSettlementValidation.js +122 -0
- package/dist/domain/bondValidation.d.ts +20 -0
- package/dist/domain/bondValidation.js +216 -3
- package/dist/index.d.ts +3 -2
- package/dist/index.js +28 -1
- package/package.json +1 -1
package/dist/domain/bond.js
CHANGED
|
@@ -1,4 +1,37 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
37
|
};
|
|
@@ -6,7 +39,29 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
39
|
exports.defineBond = defineBond;
|
|
7
40
|
exports.verifyBond = verifyBond;
|
|
8
41
|
exports.loadBond = loadBond;
|
|
42
|
+
exports.buildBondPayload = buildBondPayload;
|
|
43
|
+
exports.redeemBond = redeemBond;
|
|
44
|
+
exports.buildBondTransitionPayload = buildBondTransitionPayload;
|
|
45
|
+
exports.buildBondSettlementDescriptor = buildBondSettlementDescriptor;
|
|
46
|
+
exports.verifyBondSettlementDescriptor = verifyBondSettlementDescriptor;
|
|
47
|
+
exports.buildBondSettlementPayload = buildBondSettlementPayload;
|
|
48
|
+
exports.compileBondTransition = compileBondTransition;
|
|
49
|
+
exports.verifyBondRedemptionMachineArtifact = verifyBondRedemptionMachineArtifact;
|
|
50
|
+
exports.compileBondRedemptionMachine = compileBondRedemptionMachine;
|
|
51
|
+
exports.buildBondRedemption = buildBondRedemption;
|
|
52
|
+
exports.verifyBondTransition = verifyBondTransition;
|
|
53
|
+
exports.buildBondRolloverPlan = buildBondRolloverPlan;
|
|
54
|
+
exports.buildBondMachineRolloverPlan = buildBondMachineRolloverPlan;
|
|
55
|
+
exports.buildBondMachineSettlementPlan = buildBondMachineSettlementPlan;
|
|
56
|
+
exports.inspectBondStateRollover = inspectBondStateRollover;
|
|
57
|
+
exports.inspectBondMachineRollover = inspectBondMachineRollover;
|
|
58
|
+
exports.inspectBondMachineSettlement = inspectBondMachineSettlement;
|
|
59
|
+
exports.executeBondStateRollover = executeBondStateRollover;
|
|
60
|
+
exports.executeBondMachineRollover = executeBondMachineRollover;
|
|
61
|
+
exports.executeBondMachineSettlement = executeBondMachineSettlement;
|
|
9
62
|
const node_path_1 = __importDefault(require("node:path"));
|
|
63
|
+
const summary_1 = require("../core/summary");
|
|
64
|
+
const bondSettlementValidation_1 = require("./bondSettlementValidation");
|
|
10
65
|
const bondValidation_1 = require("./bondValidation");
|
|
11
66
|
function resolveValueOrPath(options) {
|
|
12
67
|
if (options.pathValue)
|
|
@@ -126,3 +181,862 @@ async function loadBond(sdk, input) {
|
|
|
126
181
|
},
|
|
127
182
|
};
|
|
128
183
|
}
|
|
184
|
+
async function buildBondPayload(sdk, input) {
|
|
185
|
+
const verification = await verifyBond(sdk, input);
|
|
186
|
+
const definitionValue = (0, bondValidation_1.validateBondDefinition)(JSON.parse(verification.definition.definition.canonicalJson));
|
|
187
|
+
const issuanceValue = (0, bondValidation_1.validateBondIssuanceState)(JSON.parse(verification.issuance.state.canonicalJson));
|
|
188
|
+
const issuanceSummary = (0, bondValidation_1.summarizeBondIssuanceState)(issuanceValue);
|
|
189
|
+
return {
|
|
190
|
+
artifact: verification.artifact,
|
|
191
|
+
payload: {
|
|
192
|
+
bondId: definitionValue.bondId,
|
|
193
|
+
issuanceId: issuanceValue.issuanceId,
|
|
194
|
+
definitionHash: verification.definition.definition.hash,
|
|
195
|
+
issuanceStateHash: issuanceSummary.hash,
|
|
196
|
+
previousStateHash: issuanceValue.previousStateHash ?? null,
|
|
197
|
+
contractAddress: verification.artifact.compiled.contractAddress,
|
|
198
|
+
cmr: verification.artifact.compiled.cmr,
|
|
199
|
+
anchorModes: {
|
|
200
|
+
definition: verification.artifact.definition?.anchorMode ?? "none",
|
|
201
|
+
state: verification.artifact.state?.anchorMode ?? "none",
|
|
202
|
+
},
|
|
203
|
+
status: issuanceValue.status,
|
|
204
|
+
lastTransition: issuanceValue.lastTransition
|
|
205
|
+
? {
|
|
206
|
+
type: issuanceValue.lastTransition.type,
|
|
207
|
+
amount: issuanceValue.lastTransition.amount,
|
|
208
|
+
at: issuanceValue.lastTransition.at,
|
|
209
|
+
}
|
|
210
|
+
: null,
|
|
211
|
+
principal: {
|
|
212
|
+
issued: issuanceValue.issuedPrincipal,
|
|
213
|
+
outstanding: issuanceValue.outstandingPrincipal,
|
|
214
|
+
redeemed: issuanceValue.redeemedPrincipal,
|
|
215
|
+
},
|
|
216
|
+
crossChecks: verification.crossChecks,
|
|
217
|
+
},
|
|
218
|
+
trust: {
|
|
219
|
+
definitionTrust: verification.definition.trust,
|
|
220
|
+
issuanceTrust: verification.issuance.trust,
|
|
221
|
+
},
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
function detectPreviousStateAnchor(simfSource) {
|
|
225
|
+
const source = simfSource.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:])\/\/.*$/gm, "$1");
|
|
226
|
+
if (!source.includes("{{PREVIOUS_STATE_HASH}}")) {
|
|
227
|
+
return { sourceVerified: false, reason: "PREVIOUS_STATE_HASH placeholder is missing" };
|
|
228
|
+
}
|
|
229
|
+
if (!source.includes("fn require_previous_state_anchor()")) {
|
|
230
|
+
return { sourceVerified: false, reason: "require_previous_state_anchor helper is missing" };
|
|
231
|
+
}
|
|
232
|
+
if (!source.includes("let previous_state_hash: u256 = 0x{{PREVIOUS_STATE_HASH}};")) {
|
|
233
|
+
return { sourceVerified: false, reason: "previous_state_hash assignment is missing" };
|
|
234
|
+
}
|
|
235
|
+
if (!source.includes("require_previous_state_anchor();")) {
|
|
236
|
+
return { sourceVerified: false, reason: "require_previous_state_anchor() is not called from main" };
|
|
237
|
+
}
|
|
238
|
+
if (!source.includes("require_distinct_transition_state();")) {
|
|
239
|
+
return { sourceVerified: false, reason: "require_distinct_transition_state() is not called from main" };
|
|
240
|
+
}
|
|
241
|
+
return { sourceVerified: true };
|
|
242
|
+
}
|
|
243
|
+
function toUint256Hex(value) {
|
|
244
|
+
if (!Number.isFinite(value) || value < 0 || !Number.isInteger(value)) {
|
|
245
|
+
throw new Error(`Expected a non-negative integer for uint256 conversion, got: ${value}`);
|
|
246
|
+
}
|
|
247
|
+
return value.toString(16).padStart(64, "0");
|
|
248
|
+
}
|
|
249
|
+
function toUint32Hex(value) {
|
|
250
|
+
if (!Number.isFinite(value) || value < 0 || !Number.isInteger(value) || value > 0xffffffff) {
|
|
251
|
+
throw new Error(`Expected a u32-compatible non-negative integer, got: ${value}`);
|
|
252
|
+
}
|
|
253
|
+
return value.toString(16).padStart(8, "0");
|
|
254
|
+
}
|
|
255
|
+
function hashContractAddressToUint256Hex(address) {
|
|
256
|
+
return (0, summary_1.sha256HexUtf8)(address);
|
|
257
|
+
}
|
|
258
|
+
function bondStatusToCode(status) {
|
|
259
|
+
switch (status) {
|
|
260
|
+
case "ISSUED":
|
|
261
|
+
return 1;
|
|
262
|
+
case "PARTIALLY_REDEEMED":
|
|
263
|
+
return 2;
|
|
264
|
+
case "REDEEMED":
|
|
265
|
+
return 3;
|
|
266
|
+
default: {
|
|
267
|
+
const exhaustiveCheck = status;
|
|
268
|
+
throw new Error(`Unsupported bond status: ${exhaustiveCheck}`);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
async function redeemBond(sdk, input) {
|
|
273
|
+
const definitionSource = resolveValueOrPath({
|
|
274
|
+
pathValue: input.definitionPath,
|
|
275
|
+
objectValue: input.definitionValue,
|
|
276
|
+
});
|
|
277
|
+
const previousSource = resolveValueOrPath({
|
|
278
|
+
pathValue: input.previousIssuancePath,
|
|
279
|
+
objectValue: input.previousIssuanceValue,
|
|
280
|
+
});
|
|
281
|
+
const initialDefinitionDescriptor = await sdk.loadDefinition({
|
|
282
|
+
type: "bond",
|
|
283
|
+
id: input.definitionValue?.bondId ?? "BOND-2026-001",
|
|
284
|
+
...definitionSource,
|
|
285
|
+
});
|
|
286
|
+
const definition = (0, bondValidation_1.validateBondDefinition)(JSON.parse(initialDefinitionDescriptor.canonicalJson));
|
|
287
|
+
const definitionDescriptor = await sdk.loadDefinition({
|
|
288
|
+
type: "bond",
|
|
289
|
+
id: definition.bondId,
|
|
290
|
+
...(definitionSource.jsonPath ? { jsonPath: definitionSource.jsonPath } : { value: definition }),
|
|
291
|
+
});
|
|
292
|
+
const initialPreviousStateDescriptor = await sdk.loadStateDocument({
|
|
293
|
+
type: "bond-issuance",
|
|
294
|
+
id: input.previousIssuanceValue?.issuanceId ?? "BOND-2026-001-ISSUE-1",
|
|
295
|
+
...previousSource,
|
|
296
|
+
});
|
|
297
|
+
const previousIssuance = (0, bondValidation_1.validateBondIssuanceState)(JSON.parse(initialPreviousStateDescriptor.canonicalJson));
|
|
298
|
+
(0, bondValidation_1.validateBondCrossChecks)(definition, previousIssuance);
|
|
299
|
+
const nextIssuance = (0, bondValidation_1.buildRedeemedBondIssuanceState)({
|
|
300
|
+
previous: previousIssuance,
|
|
301
|
+
amount: input.amount,
|
|
302
|
+
redeemedAt: input.redeemedAt,
|
|
303
|
+
});
|
|
304
|
+
(0, bondValidation_1.validateBondStateTransition)(previousIssuance, nextIssuance);
|
|
305
|
+
const stateDescriptor = await sdk.loadStateDocument({
|
|
306
|
+
type: "bond-issuance",
|
|
307
|
+
id: nextIssuance.issuanceId,
|
|
308
|
+
value: nextIssuance,
|
|
309
|
+
});
|
|
310
|
+
const simfPath = input.simfPath ?? node_path_1.default.resolve(process.cwd(), "docs/definitions/bond-issuance-anchor.simf");
|
|
311
|
+
return sdk.compileFromFile({
|
|
312
|
+
simfPath,
|
|
313
|
+
templateVars: {
|
|
314
|
+
MIN_HEIGHT: definition.maturityDate,
|
|
315
|
+
SIGNER_XONLY: definition.controllerXonly,
|
|
316
|
+
},
|
|
317
|
+
definition: {
|
|
318
|
+
type: definitionDescriptor.definitionType,
|
|
319
|
+
id: definitionDescriptor.definitionId,
|
|
320
|
+
schemaVersion: definitionDescriptor.schemaVersion,
|
|
321
|
+
...(definitionDescriptor.sourcePath ? { jsonPath: definitionDescriptor.sourcePath } : { value: definition }),
|
|
322
|
+
anchorMode: "on-chain-constant-committed",
|
|
323
|
+
},
|
|
324
|
+
state: {
|
|
325
|
+
type: stateDescriptor.stateType,
|
|
326
|
+
id: stateDescriptor.stateId,
|
|
327
|
+
schemaVersion: stateDescriptor.schemaVersion,
|
|
328
|
+
value: nextIssuance,
|
|
329
|
+
anchorMode: "on-chain-constant-committed",
|
|
330
|
+
},
|
|
331
|
+
artifactPath: input.artifactPath,
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
async function buildBondTransitionPayload(sdk, input) {
|
|
335
|
+
const definitionSource = resolveValueOrPath({
|
|
336
|
+
pathValue: input.definitionPath,
|
|
337
|
+
objectValue: input.definitionValue,
|
|
338
|
+
});
|
|
339
|
+
const previousSource = resolveValueOrPath({
|
|
340
|
+
pathValue: input.previousIssuancePath,
|
|
341
|
+
objectValue: input.previousIssuanceValue,
|
|
342
|
+
});
|
|
343
|
+
const nextSource = resolveValueOrPath({
|
|
344
|
+
pathValue: input.nextIssuancePath,
|
|
345
|
+
objectValue: input.nextIssuanceValue,
|
|
346
|
+
});
|
|
347
|
+
const definitionDescriptor = await sdk.loadDefinition({
|
|
348
|
+
type: "bond",
|
|
349
|
+
id: input.definitionValue?.bondId ?? "BOND-2026-001",
|
|
350
|
+
...definitionSource,
|
|
351
|
+
});
|
|
352
|
+
const previousDescriptor = await sdk.loadStateDocument({
|
|
353
|
+
type: "bond-issuance",
|
|
354
|
+
id: input.previousIssuanceValue?.issuanceId ?? "BOND-2026-001-ISSUE-1",
|
|
355
|
+
...previousSource,
|
|
356
|
+
});
|
|
357
|
+
const nextDescriptor = await sdk.loadStateDocument({
|
|
358
|
+
type: "bond-issuance",
|
|
359
|
+
id: input.nextIssuanceValue?.issuanceId ?? "BOND-2026-001-ISSUE-1",
|
|
360
|
+
...nextSource,
|
|
361
|
+
});
|
|
362
|
+
const definition = (0, bondValidation_1.validateBondDefinition)(JSON.parse(definitionDescriptor.canonicalJson));
|
|
363
|
+
const previous = (0, bondValidation_1.validateBondIssuanceState)(JSON.parse(previousDescriptor.canonicalJson));
|
|
364
|
+
const next = (0, bondValidation_1.validateBondIssuanceState)(JSON.parse(nextDescriptor.canonicalJson));
|
|
365
|
+
const previousCrossChecks = (0, bondValidation_1.validateBondCrossChecks)(definition, previous);
|
|
366
|
+
const nextCrossChecks = (0, bondValidation_1.validateBondCrossChecks)(definition, next);
|
|
367
|
+
const transition = (0, bondValidation_1.validateBondStateTransition)(previous, next);
|
|
368
|
+
return {
|
|
369
|
+
definition,
|
|
370
|
+
previous,
|
|
371
|
+
next,
|
|
372
|
+
payload: {
|
|
373
|
+
bondId: definition.bondId,
|
|
374
|
+
issuanceId: previous.issuanceId,
|
|
375
|
+
definitionHash: definitionDescriptor.hash,
|
|
376
|
+
previousStateHash: previousDescriptor.hash,
|
|
377
|
+
nextStateHash: nextDescriptor.hash,
|
|
378
|
+
previousStatus: previous.status,
|
|
379
|
+
nextStatus: next.status,
|
|
380
|
+
previousStatusCode: bondStatusToCode(previous.status),
|
|
381
|
+
nextStatusCode: bondStatusToCode(next.status),
|
|
382
|
+
transitionKind: next.lastTransition?.type ?? null,
|
|
383
|
+
redeemAmount: next.lastTransition?.type === "REDEEM" ? next.lastTransition.amount : null,
|
|
384
|
+
transitionAt: next.lastTransition?.at ?? null,
|
|
385
|
+
principal: {
|
|
386
|
+
issued: previous.issuedPrincipal,
|
|
387
|
+
previousOutstanding: previous.outstandingPrincipal,
|
|
388
|
+
nextOutstanding: next.outstandingPrincipal,
|
|
389
|
+
previousRedeemed: previous.redeemedPrincipal,
|
|
390
|
+
nextRedeemed: next.redeemedPrincipal,
|
|
391
|
+
outstandingDelta: previous.outstandingPrincipal - next.outstandingPrincipal,
|
|
392
|
+
redeemedDelta: next.redeemedPrincipal - previous.redeemedPrincipal,
|
|
393
|
+
},
|
|
394
|
+
crossChecks: {
|
|
395
|
+
previous: previousCrossChecks,
|
|
396
|
+
next: nextCrossChecks,
|
|
397
|
+
transition,
|
|
398
|
+
},
|
|
399
|
+
},
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
async function buildBondSettlementDescriptor(sdk, input) {
|
|
403
|
+
const transition = await buildBondTransitionPayload(sdk, {
|
|
404
|
+
definitionPath: input.definitionPath,
|
|
405
|
+
definitionValue: input.definitionValue,
|
|
406
|
+
previousIssuancePath: input.previousIssuancePath,
|
|
407
|
+
previousIssuanceValue: input.previousIssuanceValue,
|
|
408
|
+
nextIssuancePath: input.nextIssuancePath,
|
|
409
|
+
nextIssuanceValue: input.nextIssuanceValue,
|
|
410
|
+
});
|
|
411
|
+
const nextStateCompiled = await defineBond(sdk, {
|
|
412
|
+
definitionValue: transition.definition,
|
|
413
|
+
issuanceValue: transition.next,
|
|
414
|
+
simfPath: input.nextStateSimfPath,
|
|
415
|
+
});
|
|
416
|
+
const nextContractAddress = nextStateCompiled.deployment().contractAddress;
|
|
417
|
+
const descriptor = (0, bondSettlementValidation_1.validateBondSettlementDescriptor)({
|
|
418
|
+
settlementId: `${transition.previous.issuanceId}-SETTLEMENT-${transition.payload.nextStatus}`,
|
|
419
|
+
bondId: transition.definition.bondId,
|
|
420
|
+
issuanceId: transition.previous.issuanceId,
|
|
421
|
+
definitionHash: transition.payload.definitionHash,
|
|
422
|
+
previousStateHash: transition.payload.previousStateHash,
|
|
423
|
+
nextStateHash: transition.payload.nextStateHash,
|
|
424
|
+
previousStatus: transition.payload.previousStatus,
|
|
425
|
+
nextStatus: transition.payload.nextStatus,
|
|
426
|
+
transitionKind: "REDEEM",
|
|
427
|
+
redeemAmount: transition.payload.redeemAmount ?? 0,
|
|
428
|
+
transitionAt: transition.payload.transitionAt ?? transition.next.lastTransition?.at ?? transition.next.issuedAt,
|
|
429
|
+
assetId: transition.definition.currencyAssetId,
|
|
430
|
+
nextContractAddress,
|
|
431
|
+
nextAmountSat: input.nextAmountSat,
|
|
432
|
+
maxFeeSat: input.maxFeeSat ?? 100,
|
|
433
|
+
principal: {
|
|
434
|
+
issued: transition.payload.principal.issued,
|
|
435
|
+
previousOutstanding: transition.payload.principal.previousOutstanding,
|
|
436
|
+
nextOutstanding: transition.payload.principal.nextOutstanding,
|
|
437
|
+
previousRedeemed: transition.payload.principal.previousRedeemed,
|
|
438
|
+
nextRedeemed: transition.payload.principal.nextRedeemed,
|
|
439
|
+
},
|
|
440
|
+
});
|
|
441
|
+
const summary = (0, bondSettlementValidation_1.summarizeBondSettlementDescriptor)(descriptor);
|
|
442
|
+
return {
|
|
443
|
+
definition: transition.definition,
|
|
444
|
+
previous: transition.previous,
|
|
445
|
+
next: transition.next,
|
|
446
|
+
transition: transition.payload.crossChecks.transition,
|
|
447
|
+
nextContractAddress,
|
|
448
|
+
descriptor,
|
|
449
|
+
canonicalJson: summary.canonicalJson,
|
|
450
|
+
hash: summary.hash,
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
async function verifyBondSettlementDescriptor(sdk, input) {
|
|
454
|
+
const descriptorSource = resolveValueOrPath({
|
|
455
|
+
pathValue: input.descriptorPath,
|
|
456
|
+
objectValue: input.descriptorValue,
|
|
457
|
+
});
|
|
458
|
+
const descriptor = (0, bondSettlementValidation_1.validateBondSettlementDescriptor)(descriptorSource.jsonPath
|
|
459
|
+
? JSON.parse(await Promise.resolve().then(() => __importStar(require("node:fs/promises"))).then((fs) => fs.readFile(descriptorSource.jsonPath, "utf8")))
|
|
460
|
+
: descriptorSource.value);
|
|
461
|
+
const expected = await buildBondSettlementDescriptor(sdk, {
|
|
462
|
+
definitionPath: input.definitionPath,
|
|
463
|
+
definitionValue: input.definitionValue,
|
|
464
|
+
previousIssuancePath: input.previousIssuancePath,
|
|
465
|
+
previousIssuanceValue: input.previousIssuanceValue,
|
|
466
|
+
nextIssuancePath: input.nextIssuancePath,
|
|
467
|
+
nextIssuanceValue: input.nextIssuanceValue,
|
|
468
|
+
nextStateSimfPath: input.nextStateSimfPath,
|
|
469
|
+
nextAmountSat: input.nextAmountSat ?? descriptor.nextAmountSat,
|
|
470
|
+
maxFeeSat: input.maxFeeSat ?? descriptor.maxFeeSat,
|
|
471
|
+
});
|
|
472
|
+
const actualSummary = (0, bondSettlementValidation_1.summarizeBondSettlementDescriptor)(descriptor);
|
|
473
|
+
const matches = (0, bondSettlementValidation_1.validateBondSettlementMatchesExpected)(descriptor, expected.descriptor);
|
|
474
|
+
return {
|
|
475
|
+
ok: actualSummary.hash === expected.hash,
|
|
476
|
+
reason: actualSummary.hash === expected.hash ? undefined : "Bond settlement descriptor hash mismatch",
|
|
477
|
+
descriptor,
|
|
478
|
+
expected: expected.descriptor,
|
|
479
|
+
hash: actualSummary.hash,
|
|
480
|
+
expectedHash: expected.hash,
|
|
481
|
+
matches,
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
async function buildBondSettlementPayload(sdk, input) {
|
|
485
|
+
const result = await buildBondSettlementDescriptor(sdk, input);
|
|
486
|
+
return {
|
|
487
|
+
descriptor: result.descriptor,
|
|
488
|
+
descriptorHash: result.hash,
|
|
489
|
+
previousStateHash: result.descriptor.previousStateHash,
|
|
490
|
+
nextStateHash: result.descriptor.nextStateHash,
|
|
491
|
+
nextContractAddress: result.descriptor.nextContractAddress,
|
|
492
|
+
nextAmountSat: result.descriptor.nextAmountSat,
|
|
493
|
+
maxFeeSat: result.descriptor.maxFeeSat,
|
|
494
|
+
};
|
|
495
|
+
}
|
|
496
|
+
async function compileBondTransition(sdk, input) {
|
|
497
|
+
const transitionPayload = await buildBondTransitionPayload(sdk, {
|
|
498
|
+
definitionPath: input.definitionPath,
|
|
499
|
+
definitionValue: input.definitionValue,
|
|
500
|
+
previousIssuancePath: input.previousIssuancePath,
|
|
501
|
+
previousIssuanceValue: input.previousIssuanceValue,
|
|
502
|
+
nextIssuancePath: input.nextIssuancePath,
|
|
503
|
+
nextIssuanceValue: input.nextIssuanceValue,
|
|
504
|
+
});
|
|
505
|
+
const definitionSource = resolveValueOrPath({
|
|
506
|
+
pathValue: input.definitionPath,
|
|
507
|
+
objectValue: input.definitionValue,
|
|
508
|
+
});
|
|
509
|
+
const nextSource = resolveValueOrPath({
|
|
510
|
+
pathValue: input.nextIssuancePath,
|
|
511
|
+
objectValue: input.nextIssuanceValue,
|
|
512
|
+
});
|
|
513
|
+
const definitionDescriptor = await sdk.loadDefinition({
|
|
514
|
+
type: "bond",
|
|
515
|
+
id: transitionPayload.definition.bondId,
|
|
516
|
+
...definitionSource,
|
|
517
|
+
});
|
|
518
|
+
const nextDescriptor = await sdk.loadStateDocument({
|
|
519
|
+
type: "bond-issuance",
|
|
520
|
+
id: transitionPayload.next.issuanceId,
|
|
521
|
+
...nextSource,
|
|
522
|
+
});
|
|
523
|
+
const simfPath = input.simfPath ?? node_path_1.default.resolve(process.cwd(), "docs/definitions/bond-redemption-transition.simf");
|
|
524
|
+
const rawSource = await Promise.resolve().then(() => __importStar(require("node:fs/promises"))).then((fs) => fs.readFile(simfPath, "utf8"));
|
|
525
|
+
const previousAnchor = detectPreviousStateAnchor(rawSource);
|
|
526
|
+
if (!previousAnchor.sourceVerified) {
|
|
527
|
+
throw new Error(`Transition contract source is missing required previous-state anchor pattern: ${previousAnchor.reason}`);
|
|
528
|
+
}
|
|
529
|
+
const compiled = await sdk.compileFromFile({
|
|
530
|
+
simfPath,
|
|
531
|
+
templateVars: {
|
|
532
|
+
MIN_HEIGHT: transitionPayload.definition.maturityDate,
|
|
533
|
+
SIGNER_XONLY: transitionPayload.definition.controllerXonly,
|
|
534
|
+
PREVIOUS_STATE_HASH: transitionPayload.payload.previousStateHash,
|
|
535
|
+
},
|
|
536
|
+
definition: {
|
|
537
|
+
type: definitionDescriptor.definitionType,
|
|
538
|
+
id: definitionDescriptor.definitionId,
|
|
539
|
+
schemaVersion: definitionDescriptor.schemaVersion,
|
|
540
|
+
...(definitionDescriptor.sourcePath ? { jsonPath: definitionDescriptor.sourcePath } : { value: transitionPayload.definition }),
|
|
541
|
+
anchorMode: "on-chain-constant-committed",
|
|
542
|
+
},
|
|
543
|
+
state: {
|
|
544
|
+
type: nextDescriptor.stateType,
|
|
545
|
+
id: nextDescriptor.stateId,
|
|
546
|
+
schemaVersion: nextDescriptor.schemaVersion,
|
|
547
|
+
...(nextDescriptor.sourcePath ? { jsonPath: nextDescriptor.sourcePath } : { value: transitionPayload.next }),
|
|
548
|
+
anchorMode: "on-chain-constant-committed",
|
|
549
|
+
},
|
|
550
|
+
artifactPath: input.artifactPath,
|
|
551
|
+
});
|
|
552
|
+
return {
|
|
553
|
+
compiled,
|
|
554
|
+
previousHash: transitionPayload.payload.previousStateHash,
|
|
555
|
+
nextHash: transitionPayload.payload.nextStateHash,
|
|
556
|
+
transition: transitionPayload.payload.crossChecks.transition,
|
|
557
|
+
payload: transitionPayload.payload,
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
async function verifyBondRedemptionMachineArtifact(sdk, input) {
|
|
561
|
+
const artifact = input.artifact ?? (input.artifactPath ? (await sdk.loadArtifact(input.artifactPath)).artifact : undefined);
|
|
562
|
+
if (!artifact) {
|
|
563
|
+
throw new Error("artifactPath or artifact is required");
|
|
564
|
+
}
|
|
565
|
+
const definitionSource = resolveValueOrPath({
|
|
566
|
+
pathValue: input.definitionPath,
|
|
567
|
+
objectValue: input.definitionValue,
|
|
568
|
+
});
|
|
569
|
+
const nextSource = resolveValueOrPath({
|
|
570
|
+
pathValue: input.nextIssuancePath,
|
|
571
|
+
objectValue: input.nextIssuanceValue,
|
|
572
|
+
});
|
|
573
|
+
const definitionVerification = await sdk.verifyDefinitionAgainstArtifact({
|
|
574
|
+
artifact,
|
|
575
|
+
type: "bond",
|
|
576
|
+
id: artifact.definition?.definitionId,
|
|
577
|
+
...definitionSource,
|
|
578
|
+
});
|
|
579
|
+
const nextStateVerification = await sdk.verifyStateAgainstArtifact({
|
|
580
|
+
artifact,
|
|
581
|
+
type: "bond-issuance",
|
|
582
|
+
id: artifact.state?.stateId,
|
|
583
|
+
...nextSource,
|
|
584
|
+
});
|
|
585
|
+
const expected = await buildBondTransitionPayload(sdk, {
|
|
586
|
+
definitionPath: input.definitionPath,
|
|
587
|
+
definitionValue: input.definitionValue,
|
|
588
|
+
previousIssuancePath: input.previousIssuancePath,
|
|
589
|
+
previousIssuanceValue: input.previousIssuanceValue,
|
|
590
|
+
nextIssuancePath: input.nextIssuancePath,
|
|
591
|
+
nextIssuanceValue: input.nextIssuanceValue,
|
|
592
|
+
});
|
|
593
|
+
const expectedNextCompiled = await defineBond(sdk, {
|
|
594
|
+
definitionPath: input.definitionPath,
|
|
595
|
+
definitionValue: expected.definition,
|
|
596
|
+
issuanceValue: expected.next,
|
|
597
|
+
simfPath: input.nextStateSimfPath,
|
|
598
|
+
});
|
|
599
|
+
const expectedNextContractAddress = expectedNextCompiled.deployment().contractAddress;
|
|
600
|
+
const expectedNextContractAddressHash = hashContractAddressToUint256Hex(expectedNextContractAddress);
|
|
601
|
+
const expectedSettlement = await buildBondSettlementDescriptor(sdk, {
|
|
602
|
+
definitionValue: expected.definition,
|
|
603
|
+
previousIssuanceValue: expected.previous,
|
|
604
|
+
nextIssuanceValue: expected.next,
|
|
605
|
+
nextStateSimfPath: input.nextStateSimfPath,
|
|
606
|
+
nextAmountSat: input.nextAmountSat ?? 1900,
|
|
607
|
+
maxFeeSat: input.maxFeeSat ?? 100,
|
|
608
|
+
});
|
|
609
|
+
const templateVars = artifact.source.templateVars ?? {};
|
|
610
|
+
const committed = {
|
|
611
|
+
previousStateHash: String(templateVars.PREVIOUS_STATE_HASH ?? ""),
|
|
612
|
+
redeemAmount256: String(templateVars.REDEEM_AMOUNT_256 ?? ""),
|
|
613
|
+
transitionKind256: String(templateVars.TRANSITION_KIND_256 ?? ""),
|
|
614
|
+
redeemAmount32: String(templateVars.REDEEM_AMOUNT_32 ?? ""),
|
|
615
|
+
previousStatus32: String(templateVars.PREVIOUS_STATUS_32 ?? ""),
|
|
616
|
+
nextStatus32: String(templateVars.NEXT_STATUS_32 ?? ""),
|
|
617
|
+
previousOutstanding32: String(templateVars.PREVIOUS_OUTSTANDING_32 ?? ""),
|
|
618
|
+
previousRedeemed32: String(templateVars.PREVIOUS_REDEEMED_32 ?? ""),
|
|
619
|
+
nextOutstanding32: String(templateVars.NEXT_OUTSTANDING_32 ?? ""),
|
|
620
|
+
nextRedeemed32: String(templateVars.NEXT_REDEEMED_32 ?? ""),
|
|
621
|
+
nextContractAddressHash256: String(templateVars.NEXT_CONTRACT_ADDRESS_HASH_256 ?? ""),
|
|
622
|
+
settlementDescriptorHash256: String(templateVars.SETTLEMENT_DESCRIPTOR_HASH ?? ""),
|
|
623
|
+
};
|
|
624
|
+
const checks = {
|
|
625
|
+
previousStateHashCommitted: committed.previousStateHash === expected.payload.previousStateHash,
|
|
626
|
+
redeemAmountCommitted: committed.redeemAmount256 === toUint256Hex(expected.payload.redeemAmount ?? 0)
|
|
627
|
+
&& committed.redeemAmount32 === toUint32Hex(expected.payload.redeemAmount ?? 0),
|
|
628
|
+
transitionKindCommitted: committed.transitionKind256 === toUint256Hex(expected.payload.transitionKind === "REDEEM" ? 1 : 0),
|
|
629
|
+
statusCodesCommitted: committed.previousStatus32 === toUint32Hex(expected.payload.previousStatusCode)
|
|
630
|
+
&& committed.nextStatus32 === toUint32Hex(expected.payload.nextStatusCode),
|
|
631
|
+
principalArithmeticCommitted: committed.previousOutstanding32 === toUint32Hex(expected.payload.principal.previousOutstanding)
|
|
632
|
+
&& committed.previousRedeemed32 === toUint32Hex(expected.payload.principal.previousRedeemed)
|
|
633
|
+
&& committed.nextOutstanding32 === toUint32Hex(expected.payload.principal.nextOutstanding)
|
|
634
|
+
&& committed.nextRedeemed32 === toUint32Hex(expected.payload.principal.nextRedeemed),
|
|
635
|
+
nextContractAddressCommitted: committed.nextContractAddressHash256 === expectedNextContractAddressHash,
|
|
636
|
+
settlementDescriptorCommitted: committed.settlementDescriptorHash256 === expectedSettlement.hash,
|
|
637
|
+
};
|
|
638
|
+
const allChecks = Object.values(checks).every(Boolean);
|
|
639
|
+
return {
|
|
640
|
+
artifact,
|
|
641
|
+
definition: definitionVerification,
|
|
642
|
+
issuance: nextStateVerification,
|
|
643
|
+
expectedPayload: {
|
|
644
|
+
...expected.payload,
|
|
645
|
+
nextStateContractAddress: expectedNextContractAddress,
|
|
646
|
+
nextStateContractAddressHash: expectedNextContractAddressHash,
|
|
647
|
+
},
|
|
648
|
+
expectedSettlementDescriptor: expectedSettlement.descriptor,
|
|
649
|
+
expectedSettlementDescriptorHash: expectedSettlement.hash,
|
|
650
|
+
expectedNextContractAddress,
|
|
651
|
+
expectedNextContractAddressHash,
|
|
652
|
+
committed,
|
|
653
|
+
checks,
|
|
654
|
+
verified: definitionVerification.ok
|
|
655
|
+
&& nextStateVerification.ok
|
|
656
|
+
&& definitionVerification.trust.onChainAnchorVerified
|
|
657
|
+
&& nextStateVerification.trust.onChainAnchorVerified
|
|
658
|
+
&& allChecks,
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
async function compileBondRedemptionMachine(sdk, input) {
|
|
662
|
+
const transitionResult = await compileBondTransition(sdk, {
|
|
663
|
+
definitionPath: input.definitionPath,
|
|
664
|
+
definitionValue: input.definitionValue,
|
|
665
|
+
previousIssuancePath: input.previousIssuancePath,
|
|
666
|
+
previousIssuanceValue: input.previousIssuanceValue,
|
|
667
|
+
nextIssuancePath: input.nextIssuancePath,
|
|
668
|
+
nextIssuanceValue: input.nextIssuanceValue,
|
|
669
|
+
});
|
|
670
|
+
const definitionSource = resolveValueOrPath({
|
|
671
|
+
pathValue: input.definitionPath,
|
|
672
|
+
objectValue: input.definitionValue,
|
|
673
|
+
});
|
|
674
|
+
const nextSource = resolveValueOrPath({
|
|
675
|
+
pathValue: input.nextIssuancePath,
|
|
676
|
+
objectValue: input.nextIssuanceValue,
|
|
677
|
+
});
|
|
678
|
+
const definitionDescriptor = await sdk.loadDefinition({
|
|
679
|
+
type: "bond",
|
|
680
|
+
id: transitionResult.compiled.definition()?.definitionId ?? "BOND-2026-001",
|
|
681
|
+
...definitionSource,
|
|
682
|
+
});
|
|
683
|
+
const nextDescriptor = await sdk.loadStateDocument({
|
|
684
|
+
type: "bond-issuance",
|
|
685
|
+
id: transitionResult.compiled.state()?.stateId ?? "BOND-2026-001-ISSUE-1",
|
|
686
|
+
...nextSource,
|
|
687
|
+
});
|
|
688
|
+
const definition = (0, bondValidation_1.validateBondDefinition)(JSON.parse(definitionDescriptor.canonicalJson));
|
|
689
|
+
const next = (0, bondValidation_1.validateBondIssuanceState)(JSON.parse(nextDescriptor.canonicalJson));
|
|
690
|
+
const nextStateCompiled = await defineBond(sdk, {
|
|
691
|
+
definitionPath: input.definitionPath,
|
|
692
|
+
definitionValue: definition,
|
|
693
|
+
issuanceValue: next,
|
|
694
|
+
simfPath: input.nextStateSimfPath,
|
|
695
|
+
});
|
|
696
|
+
const nextStateContractAddress = nextStateCompiled.deployment().contractAddress;
|
|
697
|
+
const nextStateContractAddressHash = hashContractAddressToUint256Hex(nextStateContractAddress);
|
|
698
|
+
const settlementDescriptor = await buildBondSettlementDescriptor(sdk, {
|
|
699
|
+
definitionPath: input.definitionPath,
|
|
700
|
+
definitionValue: input.definitionValue ?? definition,
|
|
701
|
+
previousIssuancePath: input.previousIssuancePath,
|
|
702
|
+
previousIssuanceValue: input.previousIssuanceValue,
|
|
703
|
+
nextIssuancePath: input.nextIssuancePath,
|
|
704
|
+
nextIssuanceValue: input.nextIssuanceValue ?? next,
|
|
705
|
+
nextStateSimfPath: input.nextStateSimfPath,
|
|
706
|
+
nextAmountSat: input.nextAmountSat ?? 1900,
|
|
707
|
+
maxFeeSat: input.maxFeeSat ?? 100,
|
|
708
|
+
});
|
|
709
|
+
const simfPath = input.simfPath ?? node_path_1.default.resolve(process.cwd(), "docs/definitions/bond-redemption-state-machine.simf");
|
|
710
|
+
const compiled = await sdk.compileFromFile({
|
|
711
|
+
simfPath,
|
|
712
|
+
templateVars: {
|
|
713
|
+
MIN_HEIGHT: definition.maturityDate,
|
|
714
|
+
SIGNER_XONLY: definition.controllerXonly,
|
|
715
|
+
PREVIOUS_STATE_HASH: transitionResult.previousHash,
|
|
716
|
+
REDEEM_AMOUNT_256: toUint256Hex(next.lastTransition?.amount ?? 0),
|
|
717
|
+
TRANSITION_KIND_256: toUint256Hex(1),
|
|
718
|
+
REDEEM_AMOUNT_32: toUint32Hex(next.lastTransition?.amount ?? 0),
|
|
719
|
+
PREVIOUS_STATUS_32: toUint32Hex(bondStatusToCode(transitionResult.payload.previousStatus)),
|
|
720
|
+
NEXT_STATUS_32: toUint32Hex(bondStatusToCode(transitionResult.payload.nextStatus)),
|
|
721
|
+
PREVIOUS_OUTSTANDING_32: toUint32Hex(transitionResult.payload.principal.previousOutstanding),
|
|
722
|
+
PREVIOUS_REDEEMED_32: toUint32Hex(transitionResult.payload.principal.previousRedeemed),
|
|
723
|
+
NEXT_OUTSTANDING_32: toUint32Hex(transitionResult.payload.principal.nextOutstanding),
|
|
724
|
+
NEXT_REDEEMED_32: toUint32Hex(transitionResult.payload.principal.nextRedeemed),
|
|
725
|
+
NEXT_CONTRACT_ADDRESS_HASH_256: nextStateContractAddressHash,
|
|
726
|
+
SETTLEMENT_DESCRIPTOR_HASH: settlementDescriptor.hash,
|
|
727
|
+
},
|
|
728
|
+
definition: {
|
|
729
|
+
type: definitionDescriptor.definitionType,
|
|
730
|
+
id: definitionDescriptor.definitionId,
|
|
731
|
+
schemaVersion: definitionDescriptor.schemaVersion,
|
|
732
|
+
...(definitionDescriptor.sourcePath ? { jsonPath: definitionDescriptor.sourcePath } : { value: definition }),
|
|
733
|
+
anchorMode: "on-chain-constant-committed",
|
|
734
|
+
},
|
|
735
|
+
state: {
|
|
736
|
+
type: nextDescriptor.stateType,
|
|
737
|
+
id: nextDescriptor.stateId,
|
|
738
|
+
schemaVersion: nextDescriptor.schemaVersion,
|
|
739
|
+
...(nextDescriptor.sourcePath ? { jsonPath: nextDescriptor.sourcePath } : { value: next }),
|
|
740
|
+
anchorMode: "on-chain-constant-committed",
|
|
741
|
+
},
|
|
742
|
+
artifactPath: input.artifactPath,
|
|
743
|
+
});
|
|
744
|
+
return {
|
|
745
|
+
compiled,
|
|
746
|
+
previousHash: transitionResult.previousHash,
|
|
747
|
+
nextHash: transitionResult.nextHash,
|
|
748
|
+
transition: transitionResult.transition,
|
|
749
|
+
redeemAmount: next.lastTransition?.amount ?? 0,
|
|
750
|
+
transitionKind: "REDEEM",
|
|
751
|
+
nextStateContractAddress,
|
|
752
|
+
nextStateContractAddressHash,
|
|
753
|
+
settlementDescriptor: settlementDescriptor.descriptor,
|
|
754
|
+
settlementDescriptorHash: settlementDescriptor.hash,
|
|
755
|
+
payload: {
|
|
756
|
+
...transitionResult.payload,
|
|
757
|
+
transitionKind: "REDEEM",
|
|
758
|
+
redeemAmount: next.lastTransition?.amount ?? 0,
|
|
759
|
+
previousStatusCode: bondStatusToCode(transitionResult.payload.previousStatus),
|
|
760
|
+
nextStatusCode: bondStatusToCode(transitionResult.payload.nextStatus),
|
|
761
|
+
contractAddress: compiled.artifact.compiled.contractAddress,
|
|
762
|
+
cmr: compiled.artifact.compiled.cmr,
|
|
763
|
+
anchorModes: {
|
|
764
|
+
definition: compiled.artifact.definition?.anchorMode ?? "none",
|
|
765
|
+
state: compiled.artifact.state?.anchorMode ?? "none",
|
|
766
|
+
},
|
|
767
|
+
nextStateContractAddress,
|
|
768
|
+
nextStateContractAddressHash,
|
|
769
|
+
settlementDescriptor: settlementDescriptor.descriptor,
|
|
770
|
+
settlementDescriptorHash: settlementDescriptor.hash,
|
|
771
|
+
},
|
|
772
|
+
};
|
|
773
|
+
}
|
|
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,
|
|
792
|
+
});
|
|
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,
|
|
800
|
+
});
|
|
801
|
+
const transition = (0, bondValidation_1.validateBondStateTransition)(previous, next);
|
|
802
|
+
return {
|
|
803
|
+
definition,
|
|
804
|
+
previous,
|
|
805
|
+
next,
|
|
806
|
+
previousHash: previousDescriptor.hash,
|
|
807
|
+
nextHash: (0, bondValidation_1.summarizeBondIssuanceState)(next).hash,
|
|
808
|
+
transition,
|
|
809
|
+
};
|
|
810
|
+
}
|
|
811
|
+
async function verifyBondTransition(sdk, input) {
|
|
812
|
+
const previousSource = resolveValueOrPath({
|
|
813
|
+
pathValue: input.previousIssuancePath,
|
|
814
|
+
objectValue: input.previousIssuanceValue,
|
|
815
|
+
});
|
|
816
|
+
const nextSource = resolveValueOrPath({
|
|
817
|
+
pathValue: input.nextIssuancePath,
|
|
818
|
+
objectValue: input.nextIssuanceValue,
|
|
819
|
+
});
|
|
820
|
+
const previousDescriptor = await sdk.loadStateDocument({
|
|
821
|
+
type: "bond-issuance",
|
|
822
|
+
id: input.previousIssuanceValue?.issuanceId ?? "BOND-2026-001-ISSUE-1",
|
|
823
|
+
...previousSource,
|
|
824
|
+
});
|
|
825
|
+
const nextDescriptor = await sdk.loadStateDocument({
|
|
826
|
+
type: "bond-issuance",
|
|
827
|
+
id: input.nextIssuanceValue?.issuanceId ?? "BOND-2026-001-ISSUE-1",
|
|
828
|
+
...nextSource,
|
|
829
|
+
});
|
|
830
|
+
const previous = (0, bondValidation_1.validateBondIssuanceState)(JSON.parse(previousDescriptor.canonicalJson));
|
|
831
|
+
const next = (0, bondValidation_1.validateBondIssuanceState)(JSON.parse(nextDescriptor.canonicalJson));
|
|
832
|
+
const transition = (0, bondValidation_1.validateBondStateTransition)(previous, next);
|
|
833
|
+
return {
|
|
834
|
+
previous,
|
|
835
|
+
next,
|
|
836
|
+
previousHash: previousDescriptor.hash,
|
|
837
|
+
nextHash: nextDescriptor.hash,
|
|
838
|
+
transition,
|
|
839
|
+
};
|
|
840
|
+
}
|
|
841
|
+
async function buildBondRolloverPlan(sdk, input) {
|
|
842
|
+
const currentArtifact = input.currentArtifact
|
|
843
|
+
?? (input.currentArtifactPath ? (await sdk.loadArtifact(input.currentArtifactPath)).artifact : undefined);
|
|
844
|
+
if (!currentArtifact) {
|
|
845
|
+
throw new Error("currentArtifactPath or currentArtifact is required");
|
|
846
|
+
}
|
|
847
|
+
const currentVerification = await verifyBond(sdk, {
|
|
848
|
+
artifact: currentArtifact,
|
|
849
|
+
definitionPath: input.definitionPath,
|
|
850
|
+
definitionValue: input.definitionValue,
|
|
851
|
+
issuancePath: input.previousIssuancePath,
|
|
852
|
+
issuanceValue: input.previousIssuanceValue,
|
|
853
|
+
});
|
|
854
|
+
const definitionValue = (0, bondValidation_1.validateBondDefinition)(JSON.parse(currentVerification.definition.definition.canonicalJson));
|
|
855
|
+
const nextIssuanceSource = resolveValueOrPath({
|
|
856
|
+
pathValue: input.nextIssuancePath,
|
|
857
|
+
objectValue: input.nextIssuanceValue,
|
|
858
|
+
});
|
|
859
|
+
const nextInitialStateDescriptor = await sdk.loadStateDocument({
|
|
860
|
+
type: "bond-issuance",
|
|
861
|
+
id: input.nextIssuanceValue?.issuanceId ?? currentArtifact.state?.stateId ?? "BOND-2026-001-ISSUE-1",
|
|
862
|
+
...nextIssuanceSource,
|
|
863
|
+
});
|
|
864
|
+
const nextIssuance = (0, bondValidation_1.validateBondIssuanceState)(JSON.parse(nextInitialStateDescriptor.canonicalJson));
|
|
865
|
+
(0, bondValidation_1.validateBondCrossChecks)(definitionValue, nextIssuance);
|
|
866
|
+
const transitionPayload = await buildBondTransitionPayload(sdk, {
|
|
867
|
+
definitionPath: input.definitionPath,
|
|
868
|
+
definitionValue,
|
|
869
|
+
previousIssuancePath: input.previousIssuancePath,
|
|
870
|
+
previousIssuanceValue: currentVerification.issuance
|
|
871
|
+
? (0, bondValidation_1.validateBondIssuanceState)(JSON.parse(currentVerification.issuance.state.canonicalJson))
|
|
872
|
+
: input.previousIssuanceValue,
|
|
873
|
+
nextIssuancePath: input.nextIssuancePath,
|
|
874
|
+
nextIssuanceValue: nextIssuance,
|
|
875
|
+
});
|
|
876
|
+
const nextCompiled = await defineBond(sdk, {
|
|
877
|
+
definitionPath: input.definitionPath,
|
|
878
|
+
definitionValue,
|
|
879
|
+
issuanceValue: nextIssuance,
|
|
880
|
+
simfPath: input.nextSimfPath,
|
|
881
|
+
artifactPath: input.nextArtifactPath,
|
|
882
|
+
});
|
|
883
|
+
return {
|
|
884
|
+
currentArtifact,
|
|
885
|
+
currentVerification,
|
|
886
|
+
nextCompiled,
|
|
887
|
+
nextContractAddress: nextCompiled.deployment().contractAddress,
|
|
888
|
+
transitionPayload: transitionPayload.payload,
|
|
889
|
+
};
|
|
890
|
+
}
|
|
891
|
+
async function buildBondMachineRolloverPlan(sdk, input) {
|
|
892
|
+
const currentArtifact = input.currentArtifact
|
|
893
|
+
?? (input.currentArtifactPath ? (await sdk.loadArtifact(input.currentArtifactPath)).artifact : undefined);
|
|
894
|
+
if (!currentArtifact) {
|
|
895
|
+
throw new Error("currentArtifactPath or currentArtifact is required");
|
|
896
|
+
}
|
|
897
|
+
const currentVerification = await verifyBond(sdk, {
|
|
898
|
+
artifact: currentArtifact,
|
|
899
|
+
definitionPath: input.definitionPath,
|
|
900
|
+
definitionValue: input.definitionValue,
|
|
901
|
+
issuancePath: input.previousIssuancePath,
|
|
902
|
+
issuanceValue: input.previousIssuanceValue,
|
|
903
|
+
});
|
|
904
|
+
const machineCompiled = await compileBondRedemptionMachine(sdk, {
|
|
905
|
+
definitionPath: input.definitionPath,
|
|
906
|
+
definitionValue: input.definitionValue,
|
|
907
|
+
previousIssuancePath: input.previousIssuancePath,
|
|
908
|
+
previousIssuanceValue: input.previousIssuanceValue,
|
|
909
|
+
nextIssuancePath: input.nextIssuancePath,
|
|
910
|
+
nextIssuanceValue: input.nextIssuanceValue,
|
|
911
|
+
nextStateSimfPath: input.nextStateSimfPath,
|
|
912
|
+
simfPath: input.machineSimfPath,
|
|
913
|
+
artifactPath: input.machineArtifactPath,
|
|
914
|
+
});
|
|
915
|
+
const machineVerification = await verifyBondRedemptionMachineArtifact(sdk, {
|
|
916
|
+
artifact: machineCompiled.compiled.artifact,
|
|
917
|
+
definitionPath: input.definitionPath,
|
|
918
|
+
definitionValue: input.definitionValue,
|
|
919
|
+
previousIssuancePath: input.previousIssuancePath,
|
|
920
|
+
previousIssuanceValue: input.previousIssuanceValue,
|
|
921
|
+
nextIssuancePath: input.nextIssuancePath,
|
|
922
|
+
nextIssuanceValue: input.nextIssuanceValue,
|
|
923
|
+
nextStateSimfPath: input.nextStateSimfPath,
|
|
924
|
+
});
|
|
925
|
+
return {
|
|
926
|
+
currentArtifact,
|
|
927
|
+
currentVerification,
|
|
928
|
+
machineCompiled,
|
|
929
|
+
machineVerification,
|
|
930
|
+
nextContractAddress: machineCompiled.compiled.deployment().contractAddress,
|
|
931
|
+
transitionPayload: machineCompiled.payload,
|
|
932
|
+
};
|
|
933
|
+
}
|
|
934
|
+
async function buildBondMachineSettlementPlan(sdk, input) {
|
|
935
|
+
const currentMachineArtifact = input.currentMachineArtifact
|
|
936
|
+
?? (input.currentMachineArtifactPath ? (await sdk.loadArtifact(input.currentMachineArtifactPath)).artifact : undefined);
|
|
937
|
+
if (!currentMachineArtifact) {
|
|
938
|
+
throw new Error("currentMachineArtifactPath or currentMachineArtifact is required");
|
|
939
|
+
}
|
|
940
|
+
const machineVerification = await verifyBondRedemptionMachineArtifact(sdk, {
|
|
941
|
+
artifact: currentMachineArtifact,
|
|
942
|
+
definitionPath: input.definitionPath,
|
|
943
|
+
definitionValue: input.definitionValue,
|
|
944
|
+
previousIssuancePath: input.previousIssuancePath,
|
|
945
|
+
previousIssuanceValue: input.previousIssuanceValue,
|
|
946
|
+
nextIssuancePath: input.nextIssuancePath,
|
|
947
|
+
nextIssuanceValue: input.nextIssuanceValue,
|
|
948
|
+
nextStateSimfPath: input.nextSimfPath,
|
|
949
|
+
});
|
|
950
|
+
const definitionValue = (0, bondValidation_1.validateBondDefinition)(JSON.parse(machineVerification.definition.definition.canonicalJson));
|
|
951
|
+
const nextStateValue = (0, bondValidation_1.validateBondIssuanceState)(JSON.parse(machineVerification.issuance.state.canonicalJson));
|
|
952
|
+
const nextCompiled = await defineBond(sdk, {
|
|
953
|
+
definitionPath: input.definitionPath,
|
|
954
|
+
definitionValue,
|
|
955
|
+
issuanceValue: nextStateValue,
|
|
956
|
+
simfPath: input.nextSimfPath,
|
|
957
|
+
artifactPath: input.nextArtifactPath,
|
|
958
|
+
});
|
|
959
|
+
return {
|
|
960
|
+
currentMachineArtifact,
|
|
961
|
+
machineVerification,
|
|
962
|
+
nextCompiled,
|
|
963
|
+
nextContractAddress: nextCompiled.deployment().contractAddress,
|
|
964
|
+
transitionPayload: machineVerification.expectedPayload,
|
|
965
|
+
nextContractAddressMatchesMachineCommitment: nextCompiled.deployment().contractAddress === machineVerification.expectedNextContractAddress,
|
|
966
|
+
};
|
|
967
|
+
}
|
|
968
|
+
async function inspectBondStateRollover(sdk, input) {
|
|
969
|
+
const plan = await buildBondRolloverPlan(sdk, input);
|
|
970
|
+
const contract = sdk.fromArtifact(plan.currentArtifact);
|
|
971
|
+
const inspect = await contract.inspectCall({
|
|
972
|
+
wallet: input.wallet,
|
|
973
|
+
toAddress: plan.nextContractAddress,
|
|
974
|
+
signer: input.signer,
|
|
975
|
+
feeSat: input.feeSat,
|
|
976
|
+
utxoPolicy: input.utxoPolicy,
|
|
977
|
+
});
|
|
978
|
+
return { plan, inspect };
|
|
979
|
+
}
|
|
980
|
+
async function inspectBondMachineRollover(sdk, input) {
|
|
981
|
+
const plan = await buildBondMachineRolloverPlan(sdk, input);
|
|
982
|
+
const contract = sdk.fromArtifact(plan.currentArtifact);
|
|
983
|
+
const inspect = await contract.inspectCall({
|
|
984
|
+
wallet: input.wallet,
|
|
985
|
+
toAddress: plan.nextContractAddress,
|
|
986
|
+
signer: input.signer,
|
|
987
|
+
feeSat: input.feeSat,
|
|
988
|
+
utxoPolicy: input.utxoPolicy,
|
|
989
|
+
});
|
|
990
|
+
return { plan, inspect };
|
|
991
|
+
}
|
|
992
|
+
async function inspectBondMachineSettlement(sdk, input) {
|
|
993
|
+
const plan = await buildBondMachineSettlementPlan(sdk, input);
|
|
994
|
+
const contract = sdk.fromArtifact(plan.currentMachineArtifact);
|
|
995
|
+
const inspect = await contract.inspectCall({
|
|
996
|
+
wallet: input.wallet,
|
|
997
|
+
toAddress: plan.nextContractAddress,
|
|
998
|
+
signer: input.signer,
|
|
999
|
+
feeSat: input.feeSat,
|
|
1000
|
+
utxoPolicy: input.utxoPolicy,
|
|
1001
|
+
});
|
|
1002
|
+
return { plan, inspect };
|
|
1003
|
+
}
|
|
1004
|
+
async function executeBondStateRollover(sdk, input) {
|
|
1005
|
+
const plan = await buildBondRolloverPlan(sdk, input);
|
|
1006
|
+
const contract = sdk.fromArtifact(plan.currentArtifact);
|
|
1007
|
+
const execution = await contract.execute({
|
|
1008
|
+
wallet: input.wallet,
|
|
1009
|
+
toAddress: plan.nextContractAddress,
|
|
1010
|
+
signer: input.signer,
|
|
1011
|
+
feeSat: input.feeSat,
|
|
1012
|
+
utxoPolicy: input.utxoPolicy,
|
|
1013
|
+
broadcast: input.broadcast,
|
|
1014
|
+
});
|
|
1015
|
+
return { plan, execution };
|
|
1016
|
+
}
|
|
1017
|
+
async function executeBondMachineRollover(sdk, input) {
|
|
1018
|
+
const plan = await buildBondMachineRolloverPlan(sdk, input);
|
|
1019
|
+
const contract = sdk.fromArtifact(plan.currentArtifact);
|
|
1020
|
+
const execution = await contract.execute({
|
|
1021
|
+
wallet: input.wallet,
|
|
1022
|
+
toAddress: plan.nextContractAddress,
|
|
1023
|
+
signer: input.signer,
|
|
1024
|
+
feeSat: input.feeSat,
|
|
1025
|
+
utxoPolicy: input.utxoPolicy,
|
|
1026
|
+
broadcast: input.broadcast,
|
|
1027
|
+
});
|
|
1028
|
+
return { plan, execution };
|
|
1029
|
+
}
|
|
1030
|
+
async function executeBondMachineSettlement(sdk, input) {
|
|
1031
|
+
const plan = await buildBondMachineSettlementPlan(sdk, input);
|
|
1032
|
+
const contract = sdk.fromArtifact(plan.currentMachineArtifact);
|
|
1033
|
+
const execution = await contract.execute({
|
|
1034
|
+
wallet: input.wallet,
|
|
1035
|
+
toAddress: plan.nextContractAddress,
|
|
1036
|
+
signer: input.signer,
|
|
1037
|
+
feeSat: input.feeSat,
|
|
1038
|
+
utxoPolicy: input.utxoPolicy,
|
|
1039
|
+
broadcast: input.broadcast,
|
|
1040
|
+
});
|
|
1041
|
+
return { plan, execution };
|
|
1042
|
+
}
|