@hazbase/simplicity 0.0.5 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +645 -148
- package/dist/cli.js +2125 -159
- package/dist/client/SimplicityClient.d.ts +64 -290
- package/dist/client/SimplicityClient.js +65 -23
- package/dist/core/executor.js +67 -92
- package/dist/core/outputBinding.d.ts +61 -0
- package/dist/core/outputBinding.js +552 -0
- package/dist/core/schnorr.d.ts +5 -0
- package/dist/core/schnorr.js +34 -0
- package/dist/core/types.d.ts +553 -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 +33 -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/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 +8583 -721
- package/dist/domain/bond.js +1272 -31
- package/dist/domain/bondSettlementValidation.d.ts +2 -0
- package/dist/domain/bondSettlementValidation.js +28 -0
- package/dist/domain/bondValidation.d.ts +6 -0
- package/dist/domain/bondValidation.js +65 -3
- package/dist/domain/fund.d.ts +2069 -0
- package/dist/domain/fund.js +1384 -0
- package/dist/domain/fundValidation.d.ts +122 -0
- package/dist/domain/fundValidation.js +635 -0
- package/dist/domain/policies.d.ts +1051 -0
- package/dist/domain/policies.js +1605 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.js +85 -21
- package/package.json +15 -2
|
@@ -33,6 +33,17 @@ function validateBondSettlementDescriptor(value) {
|
|
|
33
33
|
assertFiniteNumber(descriptor?.redeemAmount, "BOND_SETTLEMENT_REDEEM_AMOUNT_INVALID", "redeemAmount must be a finite number");
|
|
34
34
|
assertFiniteNumber(descriptor?.nextAmountSat, "BOND_SETTLEMENT_AMOUNT_INVALID", "nextAmountSat must be a finite number");
|
|
35
35
|
assertFiniteNumber(descriptor?.maxFeeSat, "BOND_SETTLEMENT_MAX_FEE_INVALID", "maxFeeSat must be a finite number");
|
|
36
|
+
if (descriptor.expectedOutputDescriptorHash !== undefined && descriptor.expectedOutputDescriptorHash !== null) {
|
|
37
|
+
assertNonEmptyString(descriptor.expectedOutputDescriptorHash, "BOND_SETTLEMENT_EXPECTED_OUTPUT_DESCRIPTOR_HASH_INVALID", "expectedOutputDescriptorHash must be a non-empty string");
|
|
38
|
+
}
|
|
39
|
+
if (descriptor.outputBindingMode !== undefined
|
|
40
|
+
&& descriptor.outputBindingMode !== "none"
|
|
41
|
+
&& descriptor.outputBindingMode !== "script-bound"
|
|
42
|
+
&& descriptor.outputBindingMode !== "descriptor-bound") {
|
|
43
|
+
throw new errors_1.ValidationError("outputBindingMode must be none, script-bound, or descriptor-bound", {
|
|
44
|
+
code: "BOND_SETTLEMENT_OUTPUT_BINDING_MODE_INVALID",
|
|
45
|
+
});
|
|
46
|
+
}
|
|
36
47
|
assertFiniteNumber(descriptor?.principal?.issued, "BOND_SETTLEMENT_PRINCIPAL_INVALID", "principal.issued must be a finite number");
|
|
37
48
|
assertFiniteNumber(descriptor?.principal?.previousOutstanding, "BOND_SETTLEMENT_PRINCIPAL_INVALID", "principal.previousOutstanding must be a finite number");
|
|
38
49
|
assertFiniteNumber(descriptor?.principal?.nextOutstanding, "BOND_SETTLEMENT_PRINCIPAL_INVALID", "principal.nextOutstanding must be a finite number");
|
|
@@ -58,6 +69,11 @@ function validateBondSettlementDescriptor(value) {
|
|
|
58
69
|
code: "BOND_SETTLEMENT_MAX_FEE_INVALID",
|
|
59
70
|
});
|
|
60
71
|
}
|
|
72
|
+
if (descriptor.expectedOutputDescriptorHash && !/^[0-9a-f]{64}$/i.test(descriptor.expectedOutputDescriptorHash)) {
|
|
73
|
+
throw new errors_1.ValidationError("expectedOutputDescriptorHash must be a 64-character hex string", {
|
|
74
|
+
code: "BOND_SETTLEMENT_EXPECTED_OUTPUT_DESCRIPTOR_HASH_INVALID",
|
|
75
|
+
});
|
|
76
|
+
}
|
|
61
77
|
if (Number.isNaN(Date.parse(descriptor.transitionAt))) {
|
|
62
78
|
throw new errors_1.ValidationError("transitionAt must be an ISO8601 string", {
|
|
63
79
|
code: "BOND_SETTLEMENT_TRANSITION_AT_INVALID",
|
|
@@ -77,6 +93,8 @@ function validateBondSettlementMatchesExpected(actual, expected) {
|
|
|
77
93
|
assetIdMatch: actual.assetId === expected.assetId,
|
|
78
94
|
nextAmountSatMatch: actual.nextAmountSat === expected.nextAmountSat,
|
|
79
95
|
maxFeeSatMatch: actual.maxFeeSat === expected.maxFeeSat,
|
|
96
|
+
expectedOutputDescriptorHashMatch: (actual.expectedOutputDescriptorHash ?? null) === (expected.expectedOutputDescriptorHash ?? null),
|
|
97
|
+
outputBindingModeMatch: (actual.outputBindingMode ?? "none") === (expected.outputBindingMode ?? "none"),
|
|
80
98
|
};
|
|
81
99
|
if (!result.bondIdMatch) {
|
|
82
100
|
throw new errors_1.ValidationError("Bond settlement bondId does not match expected value", {
|
|
@@ -118,5 +136,15 @@ function validateBondSettlementMatchesExpected(actual, expected) {
|
|
|
118
136
|
code: "BOND_SETTLEMENT_AMOUNT_INVALID",
|
|
119
137
|
});
|
|
120
138
|
}
|
|
139
|
+
if (!result.expectedOutputDescriptorHashMatch) {
|
|
140
|
+
throw new errors_1.ValidationError("Bond settlement expectedOutputDescriptorHash does not match expected value", {
|
|
141
|
+
code: "BOND_SETTLEMENT_EXPECTED_OUTPUT_DESCRIPTOR_HASH_MISMATCH",
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
if (!result.outputBindingModeMatch) {
|
|
145
|
+
throw new errors_1.ValidationError("Bond settlement outputBindingMode does not match expected value", {
|
|
146
|
+
code: "BOND_SETTLEMENT_OUTPUT_BINDING_MODE_MISMATCH",
|
|
147
|
+
});
|
|
148
|
+
}
|
|
121
149
|
return result;
|
|
122
150
|
}
|
|
@@ -27,3 +27,9 @@ export declare function buildRedeemedBondIssuanceState(input: {
|
|
|
27
27
|
amount: number;
|
|
28
28
|
redeemedAt: string;
|
|
29
29
|
}): BondIssuanceState;
|
|
30
|
+
export declare function buildClosedBondIssuanceState(input: {
|
|
31
|
+
previous: BondIssuanceState;
|
|
32
|
+
closedAt: string;
|
|
33
|
+
closingReason: "REDEEMED" | "CANCELLED" | "MATURED_OUT";
|
|
34
|
+
finalSettlementDescriptorHash: string;
|
|
35
|
+
}): BondIssuanceState;
|
|
@@ -6,6 +6,7 @@ exports.validateBondIssuanceState = validateBondIssuanceState;
|
|
|
6
6
|
exports.validateBondCrossChecks = validateBondCrossChecks;
|
|
7
7
|
exports.validateBondStateTransition = validateBondStateTransition;
|
|
8
8
|
exports.buildRedeemedBondIssuanceState = buildRedeemedBondIssuanceState;
|
|
9
|
+
exports.buildClosedBondIssuanceState = buildClosedBondIssuanceState;
|
|
9
10
|
const summary_1 = require("../core/summary");
|
|
10
11
|
const errors_1 = require("../core/errors");
|
|
11
12
|
function assertNonEmptyString(value, code, message) {
|
|
@@ -19,8 +20,8 @@ function assertFiniteNumber(value, code, message) {
|
|
|
19
20
|
}
|
|
20
21
|
}
|
|
21
22
|
function assertValidStatus(status) {
|
|
22
|
-
if (status !== "ISSUED" && status !== "PARTIALLY_REDEEMED" && status !== "REDEEMED") {
|
|
23
|
-
throw new errors_1.ValidationError("status must be ISSUED, PARTIALLY_REDEEMED, or
|
|
23
|
+
if (status !== "ISSUED" && status !== "PARTIALLY_REDEEMED" && status !== "REDEEMED" && status !== "CLOSED") {
|
|
24
|
+
throw new errors_1.ValidationError("status must be ISSUED, PARTIALLY_REDEEMED, REDEEMED, or CLOSED", {
|
|
24
25
|
code: "BOND_STATUS_INVALID",
|
|
25
26
|
});
|
|
26
27
|
}
|
|
@@ -153,6 +154,40 @@ function validateBondIssuanceState(value) {
|
|
|
153
154
|
});
|
|
154
155
|
}
|
|
155
156
|
}
|
|
157
|
+
if (issuance.status === "CLOSED") {
|
|
158
|
+
if (issuance.outstandingPrincipal !== 0 || issuance.redeemedPrincipal !== issuance.issuedPrincipal) {
|
|
159
|
+
throw new errors_1.ValidationError("CLOSED state must have zero outstanding principal and full redeemed principal", {
|
|
160
|
+
code: "BOND_STATUS_TRANSITION_INVALID",
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
if (!issuance.previousStateHash) {
|
|
164
|
+
throw new errors_1.ValidationError("CLOSED state must set previousStateHash", {
|
|
165
|
+
code: "BOND_PREVIOUS_STATE_HASH_INVALID",
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
if (!issuance.closedAt || Number.isNaN(Date.parse(issuance.closedAt))) {
|
|
169
|
+
throw new errors_1.ValidationError("CLOSED state must set closedAt as an ISO8601 string", {
|
|
170
|
+
code: "BOND_CLOSED_AT_INVALID",
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
if (issuance.closingReason !== "REDEEMED"
|
|
174
|
+
&& issuance.closingReason !== "CANCELLED"
|
|
175
|
+
&& issuance.closingReason !== "MATURED_OUT") {
|
|
176
|
+
throw new errors_1.ValidationError("CLOSED state must set a valid closingReason", {
|
|
177
|
+
code: "BOND_CLOSING_REASON_INVALID",
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
if (!issuance.finalSettlementDescriptorHash || !/^[0-9a-f]{64}$/i.test(issuance.finalSettlementDescriptorHash)) {
|
|
181
|
+
throw new errors_1.ValidationError("CLOSED state must set finalSettlementDescriptorHash as a 64-character hex string", {
|
|
182
|
+
code: "BOND_FINAL_SETTLEMENT_DESCRIPTOR_HASH_INVALID",
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
if (!transition || transition.type !== "REDEEM") {
|
|
186
|
+
throw new errors_1.ValidationError("CLOSED state must carry a REDEEM transition", {
|
|
187
|
+
code: "BOND_TRANSITION_TYPE_INVALID",
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
}
|
|
156
191
|
return issuance;
|
|
157
192
|
}
|
|
158
193
|
function validateBondCrossChecks(definition, issuance) {
|
|
@@ -255,7 +290,7 @@ function validateBondStateTransition(previous, next) {
|
|
|
255
290
|
result.statusProgressionValid =
|
|
256
291
|
(previous.status === "ISSUED" || previous.status === "PARTIALLY_REDEEMED") &&
|
|
257
292
|
((next.status === "PARTIALLY_REDEEMED" && next.outstandingPrincipal > 0) ||
|
|
258
|
-
(next.status === "REDEEMED" && next.outstandingPrincipal === 0));
|
|
293
|
+
((next.status === "REDEEMED" || next.status === "CLOSED") && next.outstandingPrincipal === 0));
|
|
259
294
|
if (!result.statusProgressionValid) {
|
|
260
295
|
throw new errors_1.ValidationError("Bond issuance status progression is invalid", {
|
|
261
296
|
code: "BOND_STATUS_TRANSITION_INVALID",
|
|
@@ -301,3 +336,30 @@ function buildRedeemedBondIssuanceState(input) {
|
|
|
301
336
|
};
|
|
302
337
|
return validateBondIssuanceState(next);
|
|
303
338
|
}
|
|
339
|
+
function buildClosedBondIssuanceState(input) {
|
|
340
|
+
const previous = validateBondIssuanceState(input.previous);
|
|
341
|
+
if (previous.status !== "REDEEMED") {
|
|
342
|
+
throw new errors_1.ValidationError("Only a REDEEMED issuance state can be closed", {
|
|
343
|
+
code: "BOND_CLOSING_PRECONDITION_INVALID",
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
assertNonEmptyString(input.closedAt, "BOND_CLOSED_AT_INVALID", "closedAt must be a non-empty string");
|
|
347
|
+
if (Number.isNaN(Date.parse(input.closedAt))) {
|
|
348
|
+
throw new errors_1.ValidationError("closedAt must be an ISO8601 string", {
|
|
349
|
+
code: "BOND_CLOSED_AT_INVALID",
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
if (!/^[0-9a-f]{64}$/i.test(input.finalSettlementDescriptorHash)) {
|
|
353
|
+
throw new errors_1.ValidationError("finalSettlementDescriptorHash must be a 64-character hex string", {
|
|
354
|
+
code: "BOND_FINAL_SETTLEMENT_DESCRIPTOR_HASH_INVALID",
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
return validateBondIssuanceState({
|
|
358
|
+
...previous,
|
|
359
|
+
status: "CLOSED",
|
|
360
|
+
previousStateHash: summarizeBondIssuanceState(previous).hash,
|
|
361
|
+
closedAt: input.closedAt,
|
|
362
|
+
closingReason: input.closingReason,
|
|
363
|
+
finalSettlementDescriptorHash: input.finalSettlementDescriptorHash,
|
|
364
|
+
});
|
|
365
|
+
}
|