@hazbase/simplicity 0.4.8 → 0.4.10
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
CHANGED
|
@@ -12,7 +12,7 @@ It is intentionally narrower than a full market stack. It does **not** try to be
|
|
|
12
12
|
|
|
13
13
|
This SDK is designed to help Node developers get productive quickly, but it is still opinionated, early-stage, and best suited today to permissioned settlement pilots on Liquid.
|
|
14
14
|
|
|
15
|
-
##
|
|
15
|
+
## Strict policy lifecycle
|
|
16
16
|
|
|
17
17
|
This release extends strict-policy positions from ordinary transfers to a
|
|
18
18
|
complete controlled lifecycle:
|
|
@@ -24,7 +24,7 @@ complete controlled lifecycle:
|
|
|
24
24
|
- browser wallets can provide their own audited crypto implementation before
|
|
25
25
|
any strict-policy helper loads, avoiding extension CSP violations.
|
|
26
26
|
|
|
27
|
-
For policy-locked redemptions, Liquid x402
|
|
27
|
+
For policy-locked redemptions, Liquid x402 binds a wallet-created holder
|
|
28
28
|
signature for the locally recomputed transaction hash into the payment payload.
|
|
29
29
|
|
|
30
30
|
## What You Can Build
|
|
@@ -185,6 +185,23 @@ enough for the bounded transaction shape. Do not use it for a secondary market,
|
|
|
185
185
|
additional intermediaries, or transactions that need more inputs, outputs, or
|
|
186
186
|
approved holders.
|
|
187
187
|
|
|
188
|
+
`strict_v2_confidential` is a separate verifier profile for Atomic DvP
|
|
189
|
+
purchases. It keeps the protected RWA inputs and outputs explicit, while the
|
|
190
|
+
single treasury-payment output at index 2 uses standard Liquid confidentiality.
|
|
191
|
+
The verifier still checks strict-asset conservation and rejects confidential
|
|
192
|
+
strict outputs. A wallet must inspect the complete explicit proposal first,
|
|
193
|
+
blind only that fixed payment output locally, and sign the resulting PSET. The
|
|
194
|
+
treasury then independently unblinds and checks the payment before service
|
|
195
|
+
finalization. Existing `strict_v2` and `strict_v2_compact` positions are not
|
|
196
|
+
changed or reinterpreted by this profile.
|
|
197
|
+
|
|
198
|
+
`strict_v2_compact_confidential` applies the same fixed payment-output
|
|
199
|
+
confidentiality to the bounded pilot envelope: at most 3 inputs, 4 outputs,
|
|
200
|
+
and 2 approved holders. It is intended for one-position issuance and purchase
|
|
201
|
+
flows where the general profile would exceed the network execution budget. It
|
|
202
|
+
does not weaken the holder signature, whitelist, asset-conservation, or
|
|
203
|
+
fixed-index payment checks.
|
|
204
|
+
|
|
188
205
|
```ts
|
|
189
206
|
const verifier = normalizeStrictPolicyVerifierCovenantParams({
|
|
190
207
|
assetId,
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Strict v2 confidential-value verifier covenant.
|
|
3
|
+
*
|
|
4
|
+
* This is a distinct profile from strict-verifier-ordinary-v1. It permits a
|
|
5
|
+
* single, designated confidential payment output at index 2. Every strict
|
|
6
|
+
* RWA input and output remains explicit, and the covenant requires their
|
|
7
|
+
* aggregate amounts to match. This prevents a strict RWA from being moved
|
|
8
|
+
* through the confidential payment output while allowing standard PSET
|
|
9
|
+
* value-and-asset blinding for the payment itself.
|
|
10
|
+
*/
|
|
11
|
+
fn not(bit: bool) -> bool {
|
|
12
|
+
<u1>::into(jet::complement_1(<bool>::into(bit)))
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
fn explicit_input_asset_amount(index: u32) -> (u256, u64) {
|
|
16
|
+
let pair: (Asset1, Amount1) = unwrap(jet::input_amount(index));
|
|
17
|
+
let (asset, amount): (Asset1, Amount1) = pair;
|
|
18
|
+
let asset_bits: u256 = unwrap_right::<(u1, u256)>(asset);
|
|
19
|
+
let amount_bits: u64 = unwrap_right::<(u1, u256)>(amount);
|
|
20
|
+
(asset_bits, amount_bits)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
fn explicit_output_asset_amount(index: u32) -> (u256, u64) {
|
|
24
|
+
let pair: (Asset1, Amount1) = unwrap(jet::output_amount(index));
|
|
25
|
+
let (asset, amount): (Asset1, Amount1) = pair;
|
|
26
|
+
let asset_bits: u256 = unwrap_right::<(u1, u256)>(asset);
|
|
27
|
+
let amount_bits: u64 = unwrap_right::<(u1, u256)>(amount);
|
|
28
|
+
(asset_bits, amount_bits)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
fn add_amount(left: u64, right: u64) -> u64 {
|
|
32
|
+
let (carry, sum): (bool, u64) = jet::add_64(left, right);
|
|
33
|
+
assert!(not(carry));
|
|
34
|
+
sum
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
fn whitelist_owner_leaf(owner: Pubkey) -> u256 {
|
|
38
|
+
let tag_hash: u256 = 0x{{WHITELIST_OWNER_TAG_HASH}};
|
|
39
|
+
let ctx: Ctx8 = jet::sha_256_ctx_8_init();
|
|
40
|
+
let ctx: Ctx8 = jet::sha_256_ctx_8_add_32(ctx, tag_hash);
|
|
41
|
+
let ctx: Ctx8 = jet::sha_256_ctx_8_add_32(ctx, tag_hash);
|
|
42
|
+
let ctx: Ctx8 = jet::sha_256_ctx_8_add_32(ctx, owner);
|
|
43
|
+
jet::sha_256_ctx_8_finalize(ctx)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
fn whitelist_step(step: (bool, u256), node: u256) -> u256 {
|
|
47
|
+
let (sibling_on_left, sibling): (bool, u256) = step;
|
|
48
|
+
let tag_hash: u256 = 0x{{WHITELIST_NODE_TAG_HASH}};
|
|
49
|
+
let ctx: Ctx8 = jet::sha_256_ctx_8_init();
|
|
50
|
+
let ctx: Ctx8 = jet::sha_256_ctx_8_add_32(ctx, tag_hash);
|
|
51
|
+
let ctx: Ctx8 = jet::sha_256_ctx_8_add_32(ctx, tag_hash);
|
|
52
|
+
let ctx: Ctx8 = match sibling_on_left {
|
|
53
|
+
true => jet::sha_256_ctx_8_add_32(ctx, sibling),
|
|
54
|
+
false => jet::sha_256_ctx_8_add_32(ctx, node),
|
|
55
|
+
};
|
|
56
|
+
let ctx: Ctx8 = match sibling_on_left {
|
|
57
|
+
true => jet::sha_256_ctx_8_add_32(ctx, node),
|
|
58
|
+
false => jet::sha_256_ctx_8_add_32(ctx, sibling),
|
|
59
|
+
};
|
|
60
|
+
jet::sha_256_ctx_8_finalize(ctx)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
fn require_whitelisted(owner: Pubkey, proof: [(bool, u256); {{WHITELIST_DEPTH}}]) {
|
|
64
|
+
let leaf: u256 = whitelist_owner_leaf(owner);
|
|
65
|
+
let root: u256 = array_fold::<whitelist_step, {{WHITELIST_DEPTH}}>(proof, leaf);
|
|
66
|
+
let expected_root: u256 = 0x{{WHITELIST_ROOT}};
|
|
67
|
+
assert!(jet::eq_256(root, expected_root));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
fn canonical_holder_script_hash(owner: Pubkey) -> u256 {
|
|
71
|
+
let holder_cmr: u256 = 0x{{HOLDER_PROGRAM_CMR}};
|
|
72
|
+
let holder_leaf: u256 = jet::build_tapleaf_simplicity(holder_cmr);
|
|
73
|
+
let tapdata_ctx: Ctx8 = jet::tapdata_init();
|
|
74
|
+
let tapdata_ctx: Ctx8 = jet::sha_256_ctx_8_add_32(tapdata_ctx, owner);
|
|
75
|
+
let owner_tapdata: u256 = jet::sha_256_ctx_8_finalize(tapdata_ctx);
|
|
76
|
+
let holder_root: u256 = jet::build_tapbranch(holder_leaf, owner_tapdata);
|
|
77
|
+
let holder_internal_key: Pubkey = 0x{{HOLDER_NUMS_INTERNAL_KEY}};
|
|
78
|
+
let output_key: u256 = jet::build_taptweak(holder_internal_key, holder_root);
|
|
79
|
+
|
|
80
|
+
let script_ctx: Ctx8 = jet::sha_256_ctx_8_init();
|
|
81
|
+
let script_ctx: Ctx8 = jet::sha_256_ctx_8_add_1(script_ctx, 0x51);
|
|
82
|
+
let script_ctx: Ctx8 = jet::sha_256_ctx_8_add_1(script_ctx, 0x20);
|
|
83
|
+
let script_ctx: Ctx8 = jet::sha_256_ctx_8_add_32(script_ctx, output_key);
|
|
84
|
+
jet::sha_256_ctx_8_finalize(script_ctx)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
fn next_index(index: u32) -> u32 {
|
|
88
|
+
let (carry, next): (bool, u32) = jet::add_32(index, 1);
|
|
89
|
+
assert!(not(carry));
|
|
90
|
+
next
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
fn scan_input(unused: (), state: (u32, u64)) -> (u32, u64) {
|
|
94
|
+
let (index, strict_total): (u32, u64) = state;
|
|
95
|
+
let past_end: bool = jet::le_32(jet::num_inputs(), index);
|
|
96
|
+
let strict_total: u64 = match past_end {
|
|
97
|
+
true => strict_total,
|
|
98
|
+
false => {
|
|
99
|
+
let (asset, amount): (u256, u64) = explicit_input_asset_amount(index);
|
|
100
|
+
let strict_asset: u256 = 0x{{STRICT_ASSET_ID_JET_HEX}};
|
|
101
|
+
let is_strict: bool = jet::eq_256(asset, strict_asset);
|
|
102
|
+
match is_strict {
|
|
103
|
+
true => add_amount(strict_total, amount),
|
|
104
|
+
false => strict_total,
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
(next_index(index), strict_total)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
fn scan_output_ordinary(
|
|
112
|
+
owner_proof: (Pubkey, [(bool, u256); {{WHITELIST_DEPTH}}]),
|
|
113
|
+
state: (u32, u64)
|
|
114
|
+
) -> (u32, u64) {
|
|
115
|
+
let (index, strict_total): (u32, u64) = state;
|
|
116
|
+
let past_end: bool = jet::le_32(jet::num_outputs(), index);
|
|
117
|
+
let strict_total: u64 = match past_end {
|
|
118
|
+
true => strict_total,
|
|
119
|
+
false => {
|
|
120
|
+
let pair: (Asset1, Amount1) = unwrap(jet::output_amount(index));
|
|
121
|
+
let (asset, amount): (Asset1, Amount1) = pair;
|
|
122
|
+
match asset {
|
|
123
|
+
// PSET supports standard confidential outputs only when both
|
|
124
|
+
// asset and value are blinded. This profile permits exactly
|
|
125
|
+
// the atomic purchase payment at output 2 to use that form.
|
|
126
|
+
Left(unused_confidential_asset: (u1, u256)) => {
|
|
127
|
+
assert!(jet::eq_32(index, 2));
|
|
128
|
+
strict_total
|
|
129
|
+
},
|
|
130
|
+
Right(asset_bits: u256) => {
|
|
131
|
+
let strict_asset: u256 = 0x{{STRICT_ASSET_ID_JET_HEX}};
|
|
132
|
+
match jet::eq_256(asset_bits, strict_asset) {
|
|
133
|
+
true => {
|
|
134
|
+
let amount_bits: u64 = unwrap_right::<(u1, u256)>(amount);
|
|
135
|
+
let (owner, proof): (Pubkey, [(bool, u256); {{WHITELIST_DEPTH}}]) = owner_proof;
|
|
136
|
+
require_whitelisted(owner, proof);
|
|
137
|
+
let actual_script_hash: u256 = unwrap(jet::output_script_hash(index));
|
|
138
|
+
let expected_script_hash: u256 = canonical_holder_script_hash(owner);
|
|
139
|
+
assert!(jet::eq_256(actual_script_hash, expected_script_hash));
|
|
140
|
+
add_amount(strict_total, amount_bits)
|
|
141
|
+
},
|
|
142
|
+
false => strict_total,
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
(next_index(index), strict_total)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
fn require_verifier_successor(expected_script_hash: u256) {
|
|
152
|
+
let (verifier_asset, verifier_amount): (u256, u64) = explicit_input_asset_amount(0);
|
|
153
|
+
let expected_verifier_asset: u256 = 0x{{VERIFIER_ASSET_ID_JET_HEX}};
|
|
154
|
+
assert!(jet::eq_256(verifier_asset, expected_verifier_asset));
|
|
155
|
+
assert!(jet::eq_64(verifier_amount, {{VERIFIER_AMOUNT_ATOMIC}}));
|
|
156
|
+
|
|
157
|
+
let (successor_asset, successor_amount): (u256, u64) = explicit_output_asset_amount(0);
|
|
158
|
+
assert!(jet::eq_256(successor_asset, expected_verifier_asset));
|
|
159
|
+
assert!(jet::eq_64(successor_amount, {{VERIFIER_AMOUNT_ATOMIC}}));
|
|
160
|
+
let successor_script_hash: u256 = unwrap(jet::output_script_hash(0));
|
|
161
|
+
assert!(jet::eq_256(successor_script_hash, expected_script_hash))
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
fn scan_output_redemption(unused: (), state: (u32, u64)) -> (u32, u64) {
|
|
165
|
+
let (index, strict_total): (u32, u64) = state;
|
|
166
|
+
let past_end: bool = jet::le_32(jet::num_outputs(), index);
|
|
167
|
+
let strict_total: u64 = match past_end {
|
|
168
|
+
true => strict_total,
|
|
169
|
+
false => {
|
|
170
|
+
let pair: (Asset1, Amount1) = unwrap(jet::output_amount(index));
|
|
171
|
+
let (asset, amount): (Asset1, Amount1) = pair;
|
|
172
|
+
match asset {
|
|
173
|
+
Left(unused_confidential_asset: (u1, u256)) => {
|
|
174
|
+
assert!(false);
|
|
175
|
+
strict_total
|
|
176
|
+
},
|
|
177
|
+
Right(asset_bits: u256) => {
|
|
178
|
+
let strict_asset: u256 = 0x{{STRICT_ASSET_ID_JET_HEX}};
|
|
179
|
+
match jet::eq_256(asset_bits, strict_asset) {
|
|
180
|
+
true => {
|
|
181
|
+
let amount_bits: u64 = unwrap_right::<(u1, u256)>(amount);
|
|
182
|
+
let actual_script_hash: u256 = unwrap(jet::output_script_hash(index));
|
|
183
|
+
let redemption_script_hash: u256 = 0x{{REDEMPTION_SCRIPT_HASH}};
|
|
184
|
+
assert!(jet::eq_256(actual_script_hash, redemption_script_hash));
|
|
185
|
+
add_amount(strict_total, amount_bits)
|
|
186
|
+
},
|
|
187
|
+
false => strict_total,
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
}
|
|
191
|
+
},
|
|
192
|
+
};
|
|
193
|
+
(next_index(index), strict_total)
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
fn strict_input_total() -> u64 {
|
|
197
|
+
let input_slots: [(); {{MAX_INPUTS}}] = [{{INPUT_UNIT_SLOTS}}];
|
|
198
|
+
let input_state: (u32, u64) =
|
|
199
|
+
array_fold::<scan_input, {{MAX_INPUTS}}>(input_slots, (0, 0));
|
|
200
|
+
let (unused_input_index, strict_total): (u32, u64) = input_state;
|
|
201
|
+
strict_total
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
fn ordinary_transfer(
|
|
205
|
+
output_owner_proofs: [(Pubkey, [(bool, u256); {{WHITELIST_DEPTH}}]); {{MAX_OUTPUTS}}]
|
|
206
|
+
) {
|
|
207
|
+
require_verifier_successor(jet::current_script_hash());
|
|
208
|
+
let strict_inputs: u64 = strict_input_total();
|
|
209
|
+
assert!(not(jet::eq_64(strict_inputs, 0)));
|
|
210
|
+
|
|
211
|
+
let output_state: (u32, u64) =
|
|
212
|
+
array_fold::<scan_output_ordinary, {{MAX_OUTPUTS}}>(output_owner_proofs, (0, 0));
|
|
213
|
+
let (unused_output_index, strict_outputs): (u32, u64) = output_state;
|
|
214
|
+
assert!(jet::eq_64(strict_inputs, strict_outputs))
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
fn redemption(authority_signature: Signature) {
|
|
218
|
+
require_verifier_successor(jet::current_script_hash());
|
|
219
|
+
let strict_inputs: u64 = strict_input_total();
|
|
220
|
+
assert!(not(jet::eq_64(strict_inputs, 0)));
|
|
221
|
+
|
|
222
|
+
let output_slots: [(); {{MAX_OUTPUTS}}] = [{{OUTPUT_UNIT_SLOTS}}];
|
|
223
|
+
let output_state: (u32, u64) =
|
|
224
|
+
array_fold::<scan_output_redemption, {{MAX_OUTPUTS}}>(output_slots, (0, 0));
|
|
225
|
+
let (unused_output_index, strict_outputs): (u32, u64) = output_state;
|
|
226
|
+
assert!(jet::eq_64(strict_inputs, strict_outputs));
|
|
227
|
+
|
|
228
|
+
let authority: Pubkey = 0x{{AUTHORITY_XONLY}};
|
|
229
|
+
jet::bip_0340_verify((authority, jet::sig_all_hash()), authority_signature)
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
fn governance(next: (u256, Signature)) {
|
|
233
|
+
let (next_verifier_script_hash, authority_signature): (u256, Signature) = next;
|
|
234
|
+
require_verifier_successor(next_verifier_script_hash);
|
|
235
|
+
assert!(jet::eq_64(strict_input_total(), 0));
|
|
236
|
+
|
|
237
|
+
let output_slots: [(); {{MAX_OUTPUTS}}] = [{{OUTPUT_UNIT_SLOTS}}];
|
|
238
|
+
let output_state: (u32, u64) =
|
|
239
|
+
array_fold::<scan_output_redemption, {{MAX_OUTPUTS}}>(output_slots, (0, 0));
|
|
240
|
+
let (unused_output_index, strict_outputs): (u32, u64) = output_state;
|
|
241
|
+
assert!(jet::eq_64(strict_outputs, 0));
|
|
242
|
+
|
|
243
|
+
let authority: Pubkey = 0x{{AUTHORITY_XONLY}};
|
|
244
|
+
jet::bip_0340_verify((authority, jet::sig_all_hash()), authority_signature)
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
fn main() {
|
|
248
|
+
assert!(jet::eq_32(jet::current_index(), 0));
|
|
249
|
+
assert!(jet::le_32(jet::num_inputs(), {{MAX_INPUTS}}));
|
|
250
|
+
assert!(jet::le_32(jet::num_outputs(), {{MAX_OUTPUTS}}));
|
|
251
|
+
|
|
252
|
+
let action:
|
|
253
|
+
Either<
|
|
254
|
+
[(Pubkey, [(bool, u256); {{WHITELIST_DEPTH}}]); {{MAX_OUTPUTS}}],
|
|
255
|
+
Either<Signature, (u256, Signature)>
|
|
256
|
+
> = witness::ACTION;
|
|
257
|
+
match action {
|
|
258
|
+
Left(output_owner_proofs : [(Pubkey, [(bool, u256); {{WHITELIST_DEPTH}}]); {{MAX_OUTPUTS}}]) =>
|
|
259
|
+
ordinary_transfer(output_owner_proofs),
|
|
260
|
+
Right(protected_action : Either<Signature, (u256, Signature)>) => match protected_action {
|
|
261
|
+
Left(authority_signature : Signature) => redemption(authority_signature),
|
|
262
|
+
Right(next : (u256, Signature)) => governance(next),
|
|
263
|
+
},
|
|
264
|
+
}
|
|
265
|
+
}
|
package/dist/domain/damp.d.ts
CHANGED
|
@@ -83,7 +83,7 @@ export declare function normalizeStrictPolicyVerifierCovenantParams(value: Stric
|
|
|
83
83
|
export declare function strictPolicyHolderCovenantTemplatePath(): string;
|
|
84
84
|
export declare function renderStrictPolicyHolderCovenantSource(value: StrictPolicyHolderCovenantParams | unknown): Promise<string>;
|
|
85
85
|
export declare function compileStrictPolicyHolderCovenant(config: SimplicityClientConfig, value: StrictPolicyHolderCovenantParams | unknown): Promise<SimplicityArtifact>;
|
|
86
|
-
export declare function strictPolicyVerifierCovenantTemplatePath(): string;
|
|
86
|
+
export declare function strictPolicyVerifierCovenantTemplatePath(resourceProfile?: StrictPolicyVerifierResourceProfileId): string;
|
|
87
87
|
export declare function renderStrictPolicyVerifierCovenantSource(value: StrictPolicyVerifierCovenantParams | unknown): Promise<string>;
|
|
88
88
|
export declare function compileStrictPolicyVerifierCovenant(config: SimplicityClientConfig, value: StrictPolicyVerifierCovenantParams | unknown): Promise<SimplicityArtifact>;
|
|
89
89
|
export declare function taggedHashHexUtf8(tag: string, canonicalPayload: string): string;
|
package/dist/domain/damp.js
CHANGED
|
@@ -242,7 +242,11 @@ async function compileStrictPolicyHolderCovenant(config, value) {
|
|
|
242
242
|
},
|
|
243
243
|
});
|
|
244
244
|
}
|
|
245
|
-
function strictPolicyVerifierCovenantTemplatePath() {
|
|
245
|
+
function strictPolicyVerifierCovenantTemplatePath(resourceProfile = "strict_v2") {
|
|
246
|
+
if (resourceProfile === "strict_v2_confidential"
|
|
247
|
+
|| resourceProfile === "strict_v2_compact_confidential") {
|
|
248
|
+
return `${__dirname}/../docs/definitions/strict-verifier-confidential-v1.simf`;
|
|
249
|
+
}
|
|
246
250
|
return `${__dirname}/../docs/definitions/strict-verifier-ordinary-v1.simf`;
|
|
247
251
|
}
|
|
248
252
|
function strictPolicyVerifierTemplateVars(value) {
|
|
@@ -268,14 +272,16 @@ function strictPolicyVerifierTemplateVars(value) {
|
|
|
268
272
|
};
|
|
269
273
|
}
|
|
270
274
|
async function renderStrictPolicyVerifierCovenantSource(value) {
|
|
271
|
-
const
|
|
272
|
-
|
|
275
|
+
const params = normalizeStrictPolicyVerifierCovenantParams(value);
|
|
276
|
+
const source = await readTemplateFile(strictPolicyVerifierCovenantTemplatePath(params.resourceProfile));
|
|
277
|
+
return (0, templating_1.renderTemplate)(source, strictPolicyVerifierTemplateVars(params));
|
|
273
278
|
}
|
|
274
279
|
async function compileStrictPolicyVerifierCovenant(config, value) {
|
|
275
280
|
const { compileFromFile } = await loadCompiler();
|
|
281
|
+
const params = normalizeStrictPolicyVerifierCovenantParams(value);
|
|
276
282
|
return compileFromFile(config, {
|
|
277
|
-
simfPath: strictPolicyVerifierCovenantTemplatePath(),
|
|
278
|
-
templateVars: strictPolicyVerifierTemplateVars(
|
|
283
|
+
simfPath: strictPolicyVerifierCovenantTemplatePath(params.resourceProfile),
|
|
284
|
+
templateVars: strictPolicyVerifierTemplateVars(params),
|
|
279
285
|
});
|
|
280
286
|
}
|
|
281
287
|
function taggedHashHexUtf8(tag, canonicalPayload) {
|
|
@@ -22,6 +22,20 @@ export declare const STRICT_POLICY_VERIFIER_RESOURCE_PROFILES: {
|
|
|
22
22
|
readonly whitelistDepth: 1;
|
|
23
23
|
readonly maxWhitelistOwners: number;
|
|
24
24
|
};
|
|
25
|
+
readonly strict_v2_confidential: {
|
|
26
|
+
readonly id: "strict_v2_confidential";
|
|
27
|
+
readonly maxInputs: 16;
|
|
28
|
+
readonly maxOutputs: 8;
|
|
29
|
+
readonly whitelistDepth: 8;
|
|
30
|
+
readonly maxWhitelistOwners: number;
|
|
31
|
+
};
|
|
32
|
+
readonly strict_v2_compact_confidential: {
|
|
33
|
+
readonly id: "strict_v2_compact_confidential";
|
|
34
|
+
readonly maxInputs: 3;
|
|
35
|
+
readonly maxOutputs: 4;
|
|
36
|
+
readonly whitelistDepth: 1;
|
|
37
|
+
readonly maxWhitelistOwners: number;
|
|
38
|
+
};
|
|
25
39
|
};
|
|
26
40
|
export type StrictPolicyVerifierResourceProfileId = keyof typeof STRICT_POLICY_VERIFIER_RESOURCE_PROFILES;
|
|
27
41
|
export type StrictPolicyVerifierResourceProfile = (typeof STRICT_POLICY_VERIFIER_RESOURCE_PROFILES)[StrictPolicyVerifierResourceProfileId];
|
|
@@ -40,6 +40,24 @@ exports.STRICT_POLICY_VERIFIER_RESOURCE_PROFILES = {
|
|
|
40
40
|
whitelistDepth: exports.STRICT_POLICY_COMPACT_WHITELIST_DEPTH,
|
|
41
41
|
maxWhitelistOwners: exports.STRICT_POLICY_COMPACT_MAX_WHITELIST_OWNERS,
|
|
42
42
|
},
|
|
43
|
+
// This profile permits one full confidential treasury payment output while
|
|
44
|
+
// strict RWA inputs and outputs remain explicit for deterministic checks.
|
|
45
|
+
strict_v2_confidential: {
|
|
46
|
+
id: "strict_v2_confidential",
|
|
47
|
+
maxInputs: 16,
|
|
48
|
+
maxOutputs: 8,
|
|
49
|
+
whitelistDepth: exports.STRICT_POLICY_WHITELIST_DEPTH,
|
|
50
|
+
maxWhitelistOwners: exports.STRICT_POLICY_MAX_WHITELIST_OWNERS,
|
|
51
|
+
},
|
|
52
|
+
// Keeps the confidential treasury-payment path within the same bounded
|
|
53
|
+
// execution envelope as the initial one-position pilot.
|
|
54
|
+
strict_v2_compact_confidential: {
|
|
55
|
+
id: "strict_v2_compact_confidential",
|
|
56
|
+
maxInputs: 3,
|
|
57
|
+
maxOutputs: 4,
|
|
58
|
+
whitelistDepth: exports.STRICT_POLICY_COMPACT_WHITELIST_DEPTH,
|
|
59
|
+
maxWhitelistOwners: exports.STRICT_POLICY_COMPACT_MAX_WHITELIST_OWNERS,
|
|
60
|
+
},
|
|
43
61
|
};
|
|
44
62
|
exports.STRICT_POLICY_WHITELIST_OWNER_DOMAIN = "HAZBASE-RWA-STRICT-WHITELIST-OWNER-V1";
|
|
45
63
|
exports.STRICT_POLICY_WHITELIST_EMPTY_DOMAIN = "HAZBASE-RWA-STRICT-WHITELIST-EMPTY-V1";
|
|
@@ -52,7 +70,7 @@ function validationError(field, message) {
|
|
|
52
70
|
}
|
|
53
71
|
function resolveStrictPolicyVerifierResourceProfile(value = "strict_v2") {
|
|
54
72
|
if (typeof value !== "string" || !(value in exports.STRICT_POLICY_VERIFIER_RESOURCE_PROFILES)) {
|
|
55
|
-
validationError("resourceProfile", "must be strict_v2 or
|
|
73
|
+
validationError("resourceProfile", "must be strict_v2, strict_v2_compact, strict_v2_confidential, or strict_v2_compact_confidential");
|
|
56
74
|
}
|
|
57
75
|
return exports.STRICT_POLICY_VERIFIER_RESOURCE_PROFILES[value];
|
|
58
76
|
}
|