@hazbase/simplicity 0.0.5 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +645 -148
  2. package/dist/cli.js +2125 -159
  3. package/dist/client/SimplicityClient.d.ts +64 -290
  4. package/dist/client/SimplicityClient.js +65 -23
  5. package/dist/core/executor.js +67 -92
  6. package/dist/core/outputBinding.d.ts +61 -0
  7. package/dist/core/outputBinding.js +552 -0
  8. package/dist/core/schnorr.d.ts +5 -0
  9. package/dist/core/schnorr.js +34 -0
  10. package/dist/core/types.d.ts +553 -1
  11. package/dist/docs/definitions/bond-anchor.simf +19 -0
  12. package/dist/docs/definitions/bond-definition.json +10 -0
  13. package/dist/docs/definitions/bond-descriptor-bound-settlement-machine.simf +144 -0
  14. package/dist/docs/definitions/bond-issuance-anchor.simf +26 -0
  15. package/dist/docs/definitions/bond-issuance-state-partial-redemption.json +18 -0
  16. package/dist/docs/definitions/bond-issuance-state-redeemed.json +18 -0
  17. package/dist/docs/definitions/bond-issuance-state.json +12 -0
  18. package/dist/docs/definitions/bond-redemption-state-machine.simf +118 -0
  19. package/dist/docs/definitions/bond-redemption-transition.simf +41 -0
  20. package/dist/docs/definitions/bond-script-bound-settlement-machine.simf +142 -0
  21. package/dist/docs/definitions/fund-capital-call-open.simf +82 -0
  22. package/dist/docs/definitions/fund-capital-call-refund-only.simf +33 -0
  23. package/dist/docs/definitions/fund-capital-call-state.json +11 -0
  24. package/dist/docs/definitions/fund-definition.json +8 -0
  25. package/dist/docs/definitions/fund-distribution-claim.simf +57 -0
  26. package/dist/docs/definitions/recursive-delay-direct-next.simf +60 -0
  27. package/dist/docs/definitions/recursive-delay-optional.simf +88 -0
  28. package/dist/docs/definitions/recursive-delay-required.simf +72 -0
  29. package/dist/docs/definitions/recursive-delay.simf +83 -0
  30. package/dist/docs/definitions/recursive-policy-transfer-machine.simf +65 -0
  31. package/dist/domain/bond.d.ts +8583 -721
  32. package/dist/domain/bond.js +1272 -31
  33. package/dist/domain/bondSettlementValidation.d.ts +2 -0
  34. package/dist/domain/bondSettlementValidation.js +28 -0
  35. package/dist/domain/bondValidation.d.ts +6 -0
  36. package/dist/domain/bondValidation.js +65 -3
  37. package/dist/domain/fund.d.ts +2069 -0
  38. package/dist/domain/fund.js +1384 -0
  39. package/dist/domain/fundValidation.d.ts +122 -0
  40. package/dist/domain/fundValidation.js +635 -0
  41. package/dist/domain/policies.d.ts +1051 -0
  42. package/dist/domain/policies.js +1605 -0
  43. package/dist/index.d.ts +5 -1
  44. package/dist/index.js +85 -21
  45. package/package.json +15 -2
@@ -0,0 +1,144 @@
1
+ /*
2
+ * Bond descriptor-bound settlement machine contract.
3
+ *
4
+ * This machine commits the full settlement descriptor and additionally binds
5
+ * the next non-fee output by its runtime output hash. This is stronger than
6
+ * the script-bound machine because it constrains the full output descriptor
7
+ * represented by output_hash(0), not just the next output script.
8
+ */
9
+ fn not(bit: bool) -> bool {
10
+ <u1>::into(jet::complement_1(<bool>::into(bit)))
11
+ }
12
+
13
+ fn require_definition_anchor() {
14
+ let anchored_definition_hash: u256 = 0x{{DEFINITION_HASH}};
15
+ let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
16
+ assert!(not(jet::eq_256(anchored_definition_hash, zero_hash)));
17
+ }
18
+
19
+ fn require_previous_state_anchor() {
20
+ let previous_state_hash: u256 = 0x{{PREVIOUS_STATE_HASH}};
21
+ let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
22
+ assert!(not(jet::eq_256(previous_state_hash, zero_hash)));
23
+ }
24
+
25
+ fn require_state_anchor() {
26
+ let anchored_state_hash: u256 = 0x{{STATE_HASH}};
27
+ let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
28
+ assert!(not(jet::eq_256(anchored_state_hash, zero_hash)));
29
+ }
30
+
31
+ fn require_next_contract_address_anchor() {
32
+ let next_contract_address_hash: u256 = 0x{{NEXT_CONTRACT_ADDRESS_HASH_256}};
33
+ let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
34
+ assert!(not(jet::eq_256(next_contract_address_hash, zero_hash)));
35
+ }
36
+
37
+ fn require_settlement_descriptor_anchor() {
38
+ let settlement_descriptor_hash: u256 = 0x{{SETTLEMENT_DESCRIPTOR_HASH}};
39
+ let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
40
+ assert!(not(jet::eq_256(settlement_descriptor_hash, zero_hash)));
41
+ }
42
+
43
+ fn require_expected_output_descriptor_anchor() {
44
+ let expected_output_descriptor_hash: u256 = 0x{{EXPECTED_OUTPUT_DESCRIPTOR_HASH}};
45
+ let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
46
+ assert!(not(jet::eq_256(expected_output_descriptor_hash, zero_hash)));
47
+ }
48
+
49
+ fn require_expected_next_output_hash_anchor() {
50
+ let expected_next_output_hash: u256 = 0x{{EXPECTED_NEXT_OUTPUT_HASH_256}};
51
+ let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
52
+ assert!(not(jet::eq_256(expected_next_output_hash, zero_hash)));
53
+ }
54
+
55
+ fn require_distinct_transition_state() {
56
+ let previous_state_hash: u256 = 0x{{PREVIOUS_STATE_HASH}};
57
+ let next_state_hash: u256 = 0x{{STATE_HASH}};
58
+ assert!(not(jet::eq_256(previous_state_hash, next_state_hash)));
59
+ }
60
+
61
+ fn require_transition_kind() {
62
+ let transition_kind: u256 = 0x{{TRANSITION_KIND_256}};
63
+ let redeem_kind: u256 = 0x0000000000000000000000000000000000000000000000000000000000000001;
64
+ assert!(jet::eq_256(transition_kind, redeem_kind));
65
+ }
66
+
67
+ fn require_redeem_amount() {
68
+ let redeem_amount: u256 = 0x{{REDEEM_AMOUNT_256}};
69
+ let zero_amount: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
70
+ assert!(not(jet::eq_256(redeem_amount, zero_amount)));
71
+ }
72
+
73
+ fn require_status_progression() {
74
+ let previous_status: u32 = 0x{{PREVIOUS_STATUS_32}};
75
+ let next_status: u32 = 0x{{NEXT_STATUS_32}};
76
+ let issued_status: u32 = 0x00000001;
77
+ let partial_status: u32 = 0x00000002;
78
+ let redeemed_status: u32 = 0x00000003;
79
+
80
+ match jet::eq_32(previous_status, issued_status) {
81
+ true => {},
82
+ false => assert!(jet::eq_32(previous_status, partial_status)),
83
+ };
84
+
85
+ match jet::eq_32(next_status, partial_status) {
86
+ true => {},
87
+ false => assert!(jet::eq_32(next_status, redeemed_status)),
88
+ };
89
+ }
90
+
91
+ fn require_principal_arithmetic() {
92
+ let previous_outstanding: u32 = 0x{{PREVIOUS_OUTSTANDING_32}};
93
+ let previous_redeemed: u32 = 0x{{PREVIOUS_REDEEMED_32}};
94
+ let next_outstanding: u32 = 0x{{NEXT_OUTSTANDING_32}};
95
+ let next_redeemed: u32 = 0x{{NEXT_REDEEMED_32}};
96
+ let redeem_amount: u32 = 0x{{REDEEM_AMOUNT_32}};
97
+ let partial_status: u32 = 0x00000002;
98
+ let redeemed_status: u32 = 0x00000003;
99
+ let next_status: u32 = 0x{{NEXT_STATUS_32}};
100
+ let zero: u32 = 0x00000000;
101
+
102
+ let (underflow, computed_next_outstanding): (bool, u32) = jet::subtract_32(previous_outstanding, redeem_amount);
103
+ assert!(not(underflow));
104
+ assert!(jet::eq_32(computed_next_outstanding, next_outstanding));
105
+
106
+ let (overflow, computed_next_redeemed): (bool, u32) = jet::add_32(previous_redeemed, redeem_amount);
107
+ assert!(not(overflow));
108
+ assert!(jet::eq_32(computed_next_redeemed, next_redeemed));
109
+
110
+ match jet::eq_32(next_outstanding, zero) {
111
+ true => assert!(jet::eq_32(next_status, redeemed_status)),
112
+ false => assert!(jet::eq_32(next_status, partial_status)),
113
+ };
114
+ }
115
+
116
+ fn require_output_shape() {
117
+ assert!(jet::eq_32(jet::num_outputs(), 2));
118
+ assert!(unwrap(jet::output_is_fee(1)));
119
+ let expected_next_output_hash: u256 = 0x{{EXPECTED_NEXT_OUTPUT_HASH_256}};
120
+ let actual_next_output_hash: u256 = match jet::output_hash(0) {
121
+ Some(output_hash : u256) => output_hash,
122
+ None => panic!(),
123
+ };
124
+ assert!(jet::eq_256(actual_next_output_hash, expected_next_output_hash));
125
+ }
126
+
127
+ fn main() {
128
+ require_definition_anchor();
129
+ require_previous_state_anchor();
130
+ require_state_anchor();
131
+ require_next_contract_address_anchor();
132
+ require_settlement_descriptor_anchor();
133
+ require_expected_output_descriptor_anchor();
134
+ require_expected_next_output_hash_anchor();
135
+ require_distinct_transition_state();
136
+ require_transition_kind();
137
+ require_redeem_amount();
138
+ require_status_progression();
139
+ require_principal_arithmetic();
140
+ require_output_shape();
141
+ jet::check_lock_height({{MIN_HEIGHT}});
142
+ let signer: Pubkey = 0x{{SIGNER_XONLY}};
143
+ jet::bip_0340_verify((signer, jet::sig_all_hash()), witness::SIGNER_SIGNATURE)
144
+ }
@@ -0,0 +1,26 @@
1
+ /*
2
+ * Bond definition and issuance state hash anchors via executed logic.
3
+ */
4
+ fn not(bit: bool) -> bool {
5
+ <u1>::into(jet::complement_1(<bool>::into(bit)))
6
+ }
7
+
8
+ fn require_definition_anchor() {
9
+ let anchored_definition_hash: u256 = 0x{{DEFINITION_HASH}};
10
+ let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
11
+ assert!(not(jet::eq_256(anchored_definition_hash, zero_hash)));
12
+ }
13
+
14
+ fn require_state_anchor() {
15
+ let anchored_state_hash: u256 = 0x{{STATE_HASH}};
16
+ let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
17
+ assert!(not(jet::eq_256(anchored_state_hash, zero_hash)));
18
+ }
19
+
20
+ fn main() {
21
+ require_definition_anchor();
22
+ require_state_anchor();
23
+ jet::check_lock_height({{MIN_HEIGHT}});
24
+ let signer: Pubkey = 0x{{SIGNER_XONLY}};
25
+ jet::bip_0340_verify((signer, jet::sig_all_hash()), witness::SIGNER_SIGNATURE)
26
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "issuanceId": "BOND-2026-001-ISSUE-1",
3
+ "bondId": "BOND-2026-001",
4
+ "issuerEntityId": "hazbase-treasury",
5
+ "issuedPrincipal": 1000000,
6
+ "outstandingPrincipal": 750000,
7
+ "redeemedPrincipal": 250000,
8
+ "currencyAssetId": "bitcoin",
9
+ "controllerXonly": "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
10
+ "issuedAt": "2026-03-10T00:00:00Z",
11
+ "status": "PARTIALLY_REDEEMED",
12
+ "previousStateHash": "83a003a8b1146e839f55df4cb668eb90157fb2de4f612408fe45a82f4d22b435",
13
+ "lastTransition": {
14
+ "type": "REDEEM",
15
+ "amount": 250000,
16
+ "at": "2027-03-10T00:00:00Z"
17
+ }
18
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "issuanceId": "BOND-2026-001-ISSUE-1",
3
+ "bondId": "BOND-2026-001",
4
+ "issuerEntityId": "hazbase-treasury",
5
+ "issuedPrincipal": 1000000,
6
+ "outstandingPrincipal": 0,
7
+ "redeemedPrincipal": 1000000,
8
+ "currencyAssetId": "bitcoin",
9
+ "controllerXonly": "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
10
+ "issuedAt": "2026-03-10T00:00:00Z",
11
+ "status": "REDEEMED",
12
+ "previousStateHash": "83a003a8b1146e839f55df4cb668eb90157fb2de4f612408fe45a82f4d22b435",
13
+ "lastTransition": {
14
+ "type": "REDEEM",
15
+ "amount": 1000000,
16
+ "at": "2027-03-10T00:00:00Z"
17
+ }
18
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "issuanceId": "BOND-2026-001-ISSUE-1",
3
+ "bondId": "BOND-2026-001",
4
+ "issuerEntityId": "hazbase-treasury",
5
+ "issuedPrincipal": 1000000,
6
+ "outstandingPrincipal": 1000000,
7
+ "redeemedPrincipal": 0,
8
+ "currencyAssetId": "bitcoin",
9
+ "controllerXonly": "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
10
+ "issuedAt": "2026-03-10T00:00:00Z",
11
+ "status": "ISSUED"
12
+ }
@@ -0,0 +1,118 @@
1
+ /*
2
+ * Bond redemption state machine contract.
3
+ * Commits definition hash, previous state hash, next state hash,
4
+ * transition kind, redeem amount, status progression,
5
+ * principal arithmetic, the expected next state contract address,
6
+ * and the settlement descriptor hash
7
+ * via executed logic.
8
+ */
9
+ fn not(bit: bool) -> bool {
10
+ <u1>::into(jet::complement_1(<bool>::into(bit)))
11
+ }
12
+
13
+ fn require_definition_anchor() {
14
+ let anchored_definition_hash: u256 = 0x{{DEFINITION_HASH}};
15
+ let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
16
+ assert!(not(jet::eq_256(anchored_definition_hash, zero_hash)));
17
+ }
18
+
19
+ fn require_previous_state_anchor() {
20
+ let previous_state_hash: u256 = 0x{{PREVIOUS_STATE_HASH}};
21
+ let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
22
+ assert!(not(jet::eq_256(previous_state_hash, zero_hash)));
23
+ }
24
+
25
+ fn require_state_anchor() {
26
+ let anchored_state_hash: u256 = 0x{{STATE_HASH}};
27
+ let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
28
+ assert!(not(jet::eq_256(anchored_state_hash, zero_hash)));
29
+ }
30
+
31
+ fn require_next_contract_address_anchor() {
32
+ let next_contract_address_hash: u256 = 0x{{NEXT_CONTRACT_ADDRESS_HASH_256}};
33
+ let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
34
+ assert!(not(jet::eq_256(next_contract_address_hash, zero_hash)));
35
+ }
36
+
37
+ fn require_settlement_descriptor_anchor() {
38
+ let settlement_descriptor_hash: u256 = 0x{{SETTLEMENT_DESCRIPTOR_HASH}};
39
+ let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
40
+ assert!(not(jet::eq_256(settlement_descriptor_hash, zero_hash)));
41
+ }
42
+
43
+ fn require_distinct_transition_state() {
44
+ let previous_state_hash: u256 = 0x{{PREVIOUS_STATE_HASH}};
45
+ let next_state_hash: u256 = 0x{{STATE_HASH}};
46
+ assert!(not(jet::eq_256(previous_state_hash, next_state_hash)));
47
+ }
48
+
49
+ fn require_transition_kind() {
50
+ let transition_kind: u256 = 0x{{TRANSITION_KIND_256}};
51
+ let redeem_kind: u256 = 0x0000000000000000000000000000000000000000000000000000000000000001;
52
+ assert!(jet::eq_256(transition_kind, redeem_kind));
53
+ }
54
+
55
+ fn require_redeem_amount() {
56
+ let redeem_amount: u256 = 0x{{REDEEM_AMOUNT_256}};
57
+ let zero_amount: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
58
+ assert!(not(jet::eq_256(redeem_amount, zero_amount)));
59
+ }
60
+
61
+ fn require_status_progression() {
62
+ let previous_status: u32 = 0x{{PREVIOUS_STATUS_32}};
63
+ let next_status: u32 = 0x{{NEXT_STATUS_32}};
64
+ let issued_status: u32 = 0x00000001;
65
+ let partial_status: u32 = 0x00000002;
66
+ let redeemed_status: u32 = 0x00000003;
67
+
68
+ match jet::eq_32(previous_status, issued_status) {
69
+ true => {},
70
+ false => assert!(jet::eq_32(previous_status, partial_status)),
71
+ };
72
+
73
+ match jet::eq_32(next_status, partial_status) {
74
+ true => {},
75
+ false => assert!(jet::eq_32(next_status, redeemed_status)),
76
+ };
77
+ }
78
+
79
+ fn require_principal_arithmetic() {
80
+ let previous_outstanding: u32 = 0x{{PREVIOUS_OUTSTANDING_32}};
81
+ let previous_redeemed: u32 = 0x{{PREVIOUS_REDEEMED_32}};
82
+ let next_outstanding: u32 = 0x{{NEXT_OUTSTANDING_32}};
83
+ let next_redeemed: u32 = 0x{{NEXT_REDEEMED_32}};
84
+ let redeem_amount: u32 = 0x{{REDEEM_AMOUNT_32}};
85
+ let partial_status: u32 = 0x00000002;
86
+ let redeemed_status: u32 = 0x00000003;
87
+ let next_status: u32 = 0x{{NEXT_STATUS_32}};
88
+ let zero: u32 = 0x00000000;
89
+
90
+ let (underflow, computed_next_outstanding): (bool, u32) = jet::subtract_32(previous_outstanding, redeem_amount);
91
+ assert!(not(underflow));
92
+ assert!(jet::eq_32(computed_next_outstanding, next_outstanding));
93
+
94
+ let (overflow, computed_next_redeemed): (bool, u32) = jet::add_32(previous_redeemed, redeem_amount);
95
+ assert!(not(overflow));
96
+ assert!(jet::eq_32(computed_next_redeemed, next_redeemed));
97
+
98
+ match jet::eq_32(next_outstanding, zero) {
99
+ true => assert!(jet::eq_32(next_status, redeemed_status)),
100
+ false => assert!(jet::eq_32(next_status, partial_status)),
101
+ };
102
+ }
103
+
104
+ fn main() {
105
+ require_definition_anchor();
106
+ require_previous_state_anchor();
107
+ require_state_anchor();
108
+ require_next_contract_address_anchor();
109
+ require_settlement_descriptor_anchor();
110
+ require_distinct_transition_state();
111
+ require_transition_kind();
112
+ require_redeem_amount();
113
+ require_status_progression();
114
+ require_principal_arithmetic();
115
+ jet::check_lock_height({{MIN_HEIGHT}});
116
+ let signer: Pubkey = 0x{{SIGNER_XONLY}};
117
+ jet::bip_0340_verify((signer, jet::sig_all_hash()), witness::SIGNER_SIGNATURE)
118
+ }
@@ -0,0 +1,41 @@
1
+ /*
2
+ * Bond redemption transition contract.
3
+ * Commits definition hash, previous issuance state hash, and next issuance state hash.
4
+ */
5
+ fn not(bit: bool) -> bool {
6
+ <u1>::into(jet::complement_1(<bool>::into(bit)))
7
+ }
8
+
9
+ fn require_definition_anchor() {
10
+ let anchored_definition_hash: u256 = 0x{{DEFINITION_HASH}};
11
+ let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
12
+ assert!(not(jet::eq_256(anchored_definition_hash, zero_hash)));
13
+ }
14
+
15
+ fn require_previous_state_anchor() {
16
+ let previous_state_hash: u256 = 0x{{PREVIOUS_STATE_HASH}};
17
+ let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
18
+ assert!(not(jet::eq_256(previous_state_hash, zero_hash)));
19
+ }
20
+
21
+ fn require_state_anchor() {
22
+ let anchored_state_hash: u256 = 0x{{STATE_HASH}};
23
+ let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
24
+ assert!(not(jet::eq_256(anchored_state_hash, zero_hash)));
25
+ }
26
+
27
+ fn require_distinct_transition_state() {
28
+ let previous_state_hash: u256 = 0x{{PREVIOUS_STATE_HASH}};
29
+ let next_state_hash: u256 = 0x{{STATE_HASH}};
30
+ assert!(not(jet::eq_256(previous_state_hash, next_state_hash)));
31
+ }
32
+
33
+ fn main() {
34
+ require_definition_anchor();
35
+ require_previous_state_anchor();
36
+ require_state_anchor();
37
+ require_distinct_transition_state();
38
+ jet::check_lock_height({{MIN_HEIGHT}});
39
+ let signer: Pubkey = 0x{{SIGNER_XONLY}};
40
+ jet::bip_0340_verify((signer, jet::sig_all_hash()), witness::SIGNER_SIGNATURE)
41
+ }
@@ -0,0 +1,142 @@
1
+ /*
2
+ * Bond script-bound settlement machine contract.
3
+ *
4
+ * This machine keeps the existing redemption commitments and additionally
5
+ * constrains the settlement shape to a two-output transaction with a fee
6
+ * output in the configured fee slot. The next contract address and expected
7
+ * output descriptor remain committed data; runtime script binding is currently
8
+ * limited to output count and fee position.
9
+ */
10
+ fn not(bit: bool) -> bool {
11
+ <u1>::into(jet::complement_1(<bool>::into(bit)))
12
+ }
13
+
14
+ fn require_definition_anchor() {
15
+ let anchored_definition_hash: u256 = 0x{{DEFINITION_HASH}};
16
+ let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
17
+ assert!(not(jet::eq_256(anchored_definition_hash, zero_hash)));
18
+ }
19
+
20
+ fn require_previous_state_anchor() {
21
+ let previous_state_hash: u256 = 0x{{PREVIOUS_STATE_HASH}};
22
+ let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
23
+ assert!(not(jet::eq_256(previous_state_hash, zero_hash)));
24
+ }
25
+
26
+ fn require_state_anchor() {
27
+ let anchored_state_hash: u256 = 0x{{STATE_HASH}};
28
+ let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
29
+ assert!(not(jet::eq_256(anchored_state_hash, zero_hash)));
30
+ }
31
+
32
+ fn require_next_contract_address_anchor() {
33
+ let next_contract_address_hash: u256 = 0x{{NEXT_CONTRACT_ADDRESS_HASH_256}};
34
+ let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
35
+ assert!(not(jet::eq_256(next_contract_address_hash, zero_hash)));
36
+ }
37
+
38
+ fn require_settlement_descriptor_anchor() {
39
+ let settlement_descriptor_hash: u256 = 0x{{SETTLEMENT_DESCRIPTOR_HASH}};
40
+ let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
41
+ assert!(not(jet::eq_256(settlement_descriptor_hash, zero_hash)));
42
+ }
43
+
44
+ fn require_expected_output_descriptor_anchor() {
45
+ let expected_output_descriptor_hash: u256 = 0x{{EXPECTED_OUTPUT_DESCRIPTOR_HASH}};
46
+ let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
47
+ assert!(not(jet::eq_256(expected_output_descriptor_hash, zero_hash)));
48
+ }
49
+
50
+ fn require_expected_next_output_script_hash_anchor() {
51
+ let expected_next_output_script_hash: u256 = 0x{{EXPECTED_NEXT_OUTPUT_SCRIPT_HASH_256}};
52
+ let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
53
+ assert!(not(jet::eq_256(expected_next_output_script_hash, zero_hash)));
54
+ }
55
+
56
+ fn require_distinct_transition_state() {
57
+ let previous_state_hash: u256 = 0x{{PREVIOUS_STATE_HASH}};
58
+ let next_state_hash: u256 = 0x{{STATE_HASH}};
59
+ assert!(not(jet::eq_256(previous_state_hash, next_state_hash)));
60
+ }
61
+
62
+ fn require_transition_kind() {
63
+ let transition_kind: u256 = 0x{{TRANSITION_KIND_256}};
64
+ let redeem_kind: u256 = 0x0000000000000000000000000000000000000000000000000000000000000001;
65
+ assert!(jet::eq_256(transition_kind, redeem_kind));
66
+ }
67
+
68
+ fn require_redeem_amount() {
69
+ let redeem_amount: u256 = 0x{{REDEEM_AMOUNT_256}};
70
+ let zero_amount: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
71
+ assert!(not(jet::eq_256(redeem_amount, zero_amount)));
72
+ }
73
+
74
+ fn require_status_progression() {
75
+ let previous_status: u32 = 0x{{PREVIOUS_STATUS_32}};
76
+ let next_status: u32 = 0x{{NEXT_STATUS_32}};
77
+ let issued_status: u32 = 0x00000001;
78
+ let partial_status: u32 = 0x00000002;
79
+ let redeemed_status: u32 = 0x00000003;
80
+
81
+ match jet::eq_32(previous_status, issued_status) {
82
+ true => {},
83
+ false => assert!(jet::eq_32(previous_status, partial_status)),
84
+ };
85
+
86
+ match jet::eq_32(next_status, partial_status) {
87
+ true => {},
88
+ false => assert!(jet::eq_32(next_status, redeemed_status)),
89
+ };
90
+ }
91
+
92
+ fn require_principal_arithmetic() {
93
+ let previous_outstanding: u32 = 0x{{PREVIOUS_OUTSTANDING_32}};
94
+ let previous_redeemed: u32 = 0x{{PREVIOUS_REDEEMED_32}};
95
+ let next_outstanding: u32 = 0x{{NEXT_OUTSTANDING_32}};
96
+ let next_redeemed: u32 = 0x{{NEXT_REDEEMED_32}};
97
+ let redeem_amount: u32 = 0x{{REDEEM_AMOUNT_32}};
98
+ let partial_status: u32 = 0x00000002;
99
+ let redeemed_status: u32 = 0x00000003;
100
+ let next_status: u32 = 0x{{NEXT_STATUS_32}};
101
+ let zero: u32 = 0x00000000;
102
+
103
+ let (underflow, computed_next_outstanding): (bool, u32) = jet::subtract_32(previous_outstanding, redeem_amount);
104
+ assert!(not(underflow));
105
+ assert!(jet::eq_32(computed_next_outstanding, next_outstanding));
106
+
107
+ let (overflow, computed_next_redeemed): (bool, u32) = jet::add_32(previous_redeemed, redeem_amount);
108
+ assert!(not(overflow));
109
+ assert!(jet::eq_32(computed_next_redeemed, next_redeemed));
110
+
111
+ match jet::eq_32(next_outstanding, zero) {
112
+ true => assert!(jet::eq_32(next_status, redeemed_status)),
113
+ false => assert!(jet::eq_32(next_status, partial_status)),
114
+ };
115
+ }
116
+
117
+ fn require_output_shape() {
118
+ assert!(jet::eq_32(jet::num_outputs(), 2));
119
+ assert!(unwrap(jet::output_is_fee(1)));
120
+ let expected_next_output_script_hash: u256 = 0x{{EXPECTED_NEXT_OUTPUT_SCRIPT_HASH_256}};
121
+ let actual_next_output_script_hash: u256 = unwrap(jet::output_script_hash(0));
122
+ assert!(jet::eq_256(actual_next_output_script_hash, expected_next_output_script_hash));
123
+ }
124
+
125
+ fn main() {
126
+ require_definition_anchor();
127
+ require_previous_state_anchor();
128
+ require_state_anchor();
129
+ require_next_contract_address_anchor();
130
+ require_settlement_descriptor_anchor();
131
+ require_expected_output_descriptor_anchor();
132
+ require_expected_next_output_script_hash_anchor();
133
+ require_distinct_transition_state();
134
+ require_transition_kind();
135
+ require_redeem_amount();
136
+ require_status_progression();
137
+ require_principal_arithmetic();
138
+ require_output_shape();
139
+ jet::check_lock_height({{MIN_HEIGHT}});
140
+ let signer: Pubkey = 0x{{SIGNER_XONLY}};
141
+ jet::bip_0340_verify((signer, jet::sig_all_hash()), witness::SIGNER_SIGNATURE)
142
+ }
@@ -0,0 +1,82 @@
1
+ /*
2
+ * LP capital call open contract.
3
+ *
4
+ * LP funds the contract. The manager may claim immediately with their signature.
5
+ * After the configured cutoff height, anyone may roll the UTXO into the
6
+ * refund-only capital call state. Strict refund-only semantics are therefore
7
+ * consensus-enforced only after the rollover transaction confirms.
8
+ */
9
+ fn not(bit: bool) -> bool {
10
+ <u1>::into(jet::complement_1(<bool>::into(bit)))
11
+ }
12
+
13
+ fn require_definition_anchor() {
14
+ let anchored_definition_hash: u256 = 0x{{DEFINITION_HASH}};
15
+ let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
16
+ assert!(not(jet::eq_256(anchored_definition_hash, zero_hash)));
17
+ }
18
+
19
+ fn require_state_anchor() {
20
+ let anchored_state_hash: u256 = 0x{{STATE_HASH}};
21
+ let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
22
+ assert!(not(jet::eq_256(anchored_state_hash, zero_hash)));
23
+ }
24
+
25
+ fn require_output_shape(expected_output_hash: u256, expected_output_script_hash: u256, binding_mode: u8) {
26
+ match jet::eq_8(binding_mode, 1) {
27
+ true => {
28
+ let actual_output_hash: u256 = match jet::output_hash(0) {
29
+ Some(output_hash : u256) => output_hash,
30
+ None => panic!(),
31
+ };
32
+ assert!(jet::eq_32(jet::num_outputs(), 2));
33
+ assert!(unwrap(jet::output_is_fee(1)));
34
+ assert!(jet::eq_256(actual_output_hash, expected_output_hash));
35
+ },
36
+ false => {
37
+ match jet::eq_8(binding_mode, 2) {
38
+ true => {
39
+ let actual_output_script_hash: u256 = unwrap(jet::output_script_hash(0));
40
+ assert!(jet::eq_32(jet::num_outputs(), 2));
41
+ assert!(unwrap(jet::output_is_fee(1)));
42
+ assert!(jet::eq_256(actual_output_script_hash, expected_output_script_hash));
43
+ },
44
+ false => {},
45
+ }
46
+ },
47
+ }
48
+ }
49
+
50
+ fn claim_path(
51
+ expected_output_hash: u256,
52
+ expected_output_script_hash: u256,
53
+ binding_mode: u8,
54
+ manager_signature: Signature
55
+ ) {
56
+ require_output_shape(expected_output_hash, expected_output_script_hash, binding_mode);
57
+ let manager: Pubkey = 0x{{MANAGER_XONLY}};
58
+ jet::bip_0340_verify((manager, jet::sig_all_hash()), manager_signature)
59
+ }
60
+
61
+ fn rollover_path() {
62
+ let refund_only_script_hash: u256 = 0x{{REFUND_ONLY_SCRIPT_HASH}};
63
+ jet::check_lock_height({{CLAIM_CUTOFF_HEIGHT}});
64
+ let actual_output_script_hash: u256 = unwrap(jet::output_script_hash(0));
65
+ assert!(jet::eq_32(jet::num_outputs(), 2));
66
+ assert!(unwrap(jet::output_is_fee(1)));
67
+ assert!(jet::eq_256(actual_output_script_hash, refund_only_script_hash));
68
+ }
69
+
70
+ fn main() {
71
+ require_definition_anchor();
72
+ require_state_anchor();
73
+ let action_8: u8 = witness::ACTION_8;
74
+ let expected_output_hash: u256 = witness::EXPECTED_PAYOUT_OUTPUT_HASH;
75
+ let expected_output_script_hash: u256 = witness::EXPECTED_PAYOUT_OUTPUT_SCRIPT_HASH;
76
+ let binding_mode: u8 = witness::OUTPUT_BINDING_MODE;
77
+ let signer_signature: Signature = witness::SIGNER_SIGNATURE;
78
+ match jet::eq_8(action_8, 1) {
79
+ true => claim_path(expected_output_hash, expected_output_script_hash, binding_mode, signer_signature),
80
+ false => rollover_path(),
81
+ }
82
+ }
@@ -0,0 +1,33 @@
1
+ /*
2
+ * LP capital call refund-only contract.
3
+ *
4
+ * This artifact is reached only after the open capital call is explicitly
5
+ * rolled over post-cutoff. Once in this state, only the LP refund path remains.
6
+ */
7
+ fn not(bit: bool) -> bool {
8
+ <u1>::into(jet::complement_1(<bool>::into(bit)))
9
+ }
10
+
11
+ fn require_definition_anchor() {
12
+ let anchored_definition_hash: u256 = 0x{{DEFINITION_HASH}};
13
+ let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
14
+ assert!(not(jet::eq_256(anchored_definition_hash, zero_hash)));
15
+ }
16
+
17
+ fn require_state_anchor() {
18
+ let anchored_state_hash: u256 = 0x{{STATE_HASH}};
19
+ let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
20
+ assert!(not(jet::eq_256(anchored_state_hash, zero_hash)));
21
+ }
22
+
23
+ fn refund_path(lp_signature: Signature) {
24
+ let lp: Pubkey = 0x{{LP_XONLY}};
25
+ jet::bip_0340_verify((lp, jet::sig_all_hash()), lp_signature)
26
+ }
27
+
28
+ fn main() {
29
+ require_definition_anchor();
30
+ require_state_anchor();
31
+ let signer_signature: Signature = witness::SIGNER_SIGNATURE;
32
+ refund_path(signer_signature)
33
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "callId": "CALL-001",
3
+ "fundId": "FUND-2026-ALPHA",
4
+ "lpId": "lp-a",
5
+ "currencyAssetId": "bitcoin",
6
+ "amount": 6000,
7
+ "lpXonly": "f9308a019258c3106ac5d2d1c1d7d7f3c2e5f5b7a9e3d5f2c1a6b8c9d0e1f2a3",
8
+ "managerXonly": "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
9
+ "status": "OPEN",
10
+ "claimCutoffHeight": 2345678
11
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "fundId": "FUND-2026-ALPHA",
3
+ "managerEntityId": "manager-a",
4
+ "managerXonly": "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
5
+ "currencyAssetId": "bitcoin",
6
+ "jurisdiction": "JP",
7
+ "vintage": "2026"
8
+ }