@intentlayer/sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1112 @@
1
+ import {
2
+ __esm
3
+ } from "./chunk-XP4I75K7.mjs";
4
+
5
+ // src/constraints.ts
6
+ import { keccak256, encodePacked, decodeAbiParameters } from "viem";
7
+ function toBigEndianUint128(value) {
8
+ if (value >= 1n << 128n) {
9
+ throw new Error("Value exceeds uint128 maximum");
10
+ }
11
+ const shifted = value << 128n;
12
+ const hex = shifted.toString(16).padStart(64, "0");
13
+ const high16Bytes = hex.slice(0, 32);
14
+ return `0x${high16Bytes}`;
15
+ }
16
+ function toBigEndianUint48(value) {
17
+ if (value >= 281474976710656) {
18
+ throw new Error("Value exceeds uint48 maximum");
19
+ }
20
+ const shifted = BigInt(value) << 208n;
21
+ const hex = shifted.toString(16).padStart(64, "0");
22
+ const high6Bytes = hex.slice(0, 12);
23
+ return `0x${high6Bytes}`;
24
+ }
25
+ function toBigEndianUint32(value) {
26
+ if (value >= 4294967296) {
27
+ throw new Error("Value exceeds uint32 maximum");
28
+ }
29
+ const shifted = BigInt(value) << 224n;
30
+ const hex = shifted.toString(16).padStart(64, "0");
31
+ const high4Bytes = hex.slice(0, 8);
32
+ return `0x${high4Bytes}`;
33
+ }
34
+ function toBigEndianInt16(value) {
35
+ if (value < -32768 || value > 32767) {
36
+ throw new Error("Value exceeds int16 range");
37
+ }
38
+ const unsignedValue = value < 0 ? 65536 + value : value;
39
+ const shifted = BigInt(unsignedValue) << 240n;
40
+ const hex = shifted.toString(16).padStart(64, "0");
41
+ const high2Bytes = hex.slice(0, 4);
42
+ return `0x${high2Bytes}`;
43
+ }
44
+ function toBigEndianUint16(value) {
45
+ if (value >= 65536) {
46
+ throw new Error("Value exceeds uint16 maximum");
47
+ }
48
+ const shifted = BigInt(value) << 240n;
49
+ const hex = shifted.toString(16).padStart(64, "0");
50
+ const high2Bytes = hex.slice(0, 4);
51
+ return `0x${high2Bytes}`;
52
+ }
53
+ function createConstraintBuilder() {
54
+ return new CompoundLeafBuilder();
55
+ }
56
+ function getLeafAndProofForRecipient(policy, recipient, asset) {
57
+ const assetKey = asset || "0x0000000000000000000000000000000000000000";
58
+ const key = `${recipient.toLowerCase()}-${assetKey.toLowerCase()}`;
59
+ const proof = policy.leafProofs[key];
60
+ return proof || null;
61
+ }
62
+ function isRecipientAllowed(policy, recipient, asset) {
63
+ const assetKey = asset || "0x0000000000000000000000000000000000000000";
64
+ const key = `${recipient.toLowerCase()}-${assetKey.toLowerCase()}`;
65
+ return key in policy.leafProofs;
66
+ }
67
+ function buildConstraintCalldata(wallet, asset, recipient, amount) {
68
+ if (amount >= 1n << 128n) {
69
+ throw new Error("Amount exceeds uint128 maximum");
70
+ }
71
+ return encodePacked(
72
+ ["address", "address", "address", "uint128"],
73
+ [wallet, asset, recipient, amount]
74
+ );
75
+ }
76
+ function buildConstraintCalldataFromIntent(intent, wallet) {
77
+ return buildConstraintCalldata(
78
+ wallet,
79
+ intent.asset,
80
+ intent.recipient,
81
+ intent.amount
82
+ );
83
+ }
84
+ function extractConstraintDataFromOperations(operationsBundle, owner) {
85
+ try {
86
+ const operations = decodeAbiParameters(
87
+ [{
88
+ type: "tuple[]",
89
+ components: [
90
+ { type: "uint8", name: "opType" },
91
+ { type: "address", name: "target" },
92
+ { type: "uint256", name: "value" },
93
+ { type: "bytes", name: "data" }
94
+ ]
95
+ }],
96
+ operationsBundle
97
+ )[0];
98
+ const transferOp = operations.find((op) => op.opType === 2);
99
+ if (!transferOp) {
100
+ return null;
101
+ }
102
+ const [recipient, amount] = decodeAbiParameters(
103
+ [{ type: "address" }, { type: "uint256" }],
104
+ transferOp.data
105
+ );
106
+ const token = transferOp.target;
107
+ const constraintCalldata = buildConstraintCalldataFromIntent(
108
+ { asset: token, recipient, amount },
109
+ owner
110
+ );
111
+ return {
112
+ constraintCalldata,
113
+ token,
114
+ recipient,
115
+ amount
116
+ };
117
+ } catch (error) {
118
+ console.error("Failed to extract constraint data from operations:", error);
119
+ return null;
120
+ }
121
+ }
122
+ var DOMAIN_PREFIX2, TAG_COMPOUND_EMPLOYEE2, COMPOUND_LEAF_VERSION, FLAG_RECIPIENT, FLAG_CAP, FLAG_DEADLINE, FLAG_ASSET, FLAG_BUCKET, FLAG_PERIOD, FLAG_VENDOR_GROUP, DOMAIN_V3, VERSION_V3, TAG_COMPOUND_V3, FLAG_TARGET, FLAG_SELECTOR_LIST, FLAG_NO_BRIDGE, FLAG_OPS_HASH, PERIOD_NONE2, PERIOD_DAILY2, PERIOD_WEEKLY2, PERIOD_MONTH302, PERIOD_CUSTOM2, CompoundLeafBuilder, CompoundLeafV3Builder;
123
+ var init_constraints = __esm({
124
+ "src/constraints.ts"() {
125
+ "use strict";
126
+ DOMAIN_PREFIX2 = keccak256("IEL_CONSTRAINT_LEAF_V1").slice(0, 10);
127
+ TAG_COMPOUND_EMPLOYEE2 = 16;
128
+ COMPOUND_LEAF_VERSION = 1;
129
+ FLAG_RECIPIENT = 1;
130
+ FLAG_CAP = 2;
131
+ FLAG_DEADLINE = 4;
132
+ FLAG_ASSET = 8;
133
+ FLAG_BUCKET = 16;
134
+ FLAG_PERIOD = 32;
135
+ FLAG_VENDOR_GROUP = 64;
136
+ DOMAIN_V3 = "0x49454C33";
137
+ VERSION_V3 = 3;
138
+ TAG_COMPOUND_V3 = 32;
139
+ FLAG_TARGET = 2048;
140
+ FLAG_SELECTOR_LIST = 4096;
141
+ FLAG_NO_BRIDGE = 8192;
142
+ FLAG_OPS_HASH = 16384;
143
+ PERIOD_NONE2 = 0;
144
+ PERIOD_DAILY2 = 1;
145
+ PERIOD_WEEKLY2 = 2;
146
+ PERIOD_MONTH302 = 3;
147
+ PERIOD_CUSTOM2 = 4;
148
+ CompoundLeafBuilder = class {
149
+ /**
150
+ * Build compound constraint leaf with TLV encoding
151
+ *
152
+ * Format: [4B domain_prefix][1B tag][1B version][1B flags][conditional_fields...]
153
+ * Matches foundry test _buildCompoundLeaf exactly
154
+ */
155
+ buildCompoundLeaf(constraints) {
156
+ let flags = 0;
157
+ if (constraints.allowedAsset) {
158
+ if (!constraints.allowedAsset.match(/^0x[a-fA-F0-9]{40}$/)) {
159
+ throw new Error(`Invalid asset address: ${constraints.allowedAsset}`);
160
+ }
161
+ flags |= FLAG_ASSET;
162
+ }
163
+ if (constraints.allowedRecipient) {
164
+ if (!constraints.allowedRecipient.match(/^0x[a-fA-F0-9]{40}$/)) {
165
+ throw new Error(`Invalid recipient address: ${constraints.allowedRecipient}`);
166
+ }
167
+ flags |= FLAG_RECIPIENT;
168
+ }
169
+ if (constraints.maxAmount !== void 0) {
170
+ if (constraints.maxAmount <= 0n) {
171
+ throw new Error("Amount must be positive");
172
+ }
173
+ if (constraints.maxAmount >= 1n << 128n) {
174
+ throw new Error("Amount exceeds uint128 maximum");
175
+ }
176
+ flags |= FLAG_CAP;
177
+ }
178
+ if (constraints.deadline !== void 0) {
179
+ const currentTimestamp = Math.floor(Date.now() / 1e3);
180
+ if (constraints.deadline <= currentTimestamp) {
181
+ throw new Error("Deadline must be in the future");
182
+ }
183
+ const maxUint48 = 2n ** 48n - 1n;
184
+ if (BigInt(constraints.deadline) >= maxUint48) {
185
+ throw new Error("Deadline exceeds uint48 maximum");
186
+ }
187
+ flags |= FLAG_DEADLINE;
188
+ }
189
+ if (constraints.bucketId) {
190
+ if (!constraints.bucketId.match(/^0x[a-fA-F0-9]{64}$/)) {
191
+ throw new Error(`Invalid bucketId format: ${constraints.bucketId}`);
192
+ }
193
+ flags |= FLAG_BUCKET;
194
+ }
195
+ if (constraints.periodCode !== void 0) {
196
+ console.log("\u{1F50D} SDK DEBUG: Period constraint validation triggered");
197
+ console.log("\u{1F50D} SDK DEBUG: periodCode:", constraints.periodCode);
198
+ console.log("\u{1F50D} SDK DEBUG: FLAG_PERIOD value:", FLAG_PERIOD);
199
+ if (constraints.periodCode < 0 || constraints.periodCode > 4) {
200
+ throw new Error(`Invalid period code: ${constraints.periodCode}`);
201
+ }
202
+ flags |= FLAG_PERIOD;
203
+ console.log("\u{1F50D} SDK DEBUG: flags after adding FLAG_PERIOD:", flags);
204
+ if (constraints.offsetMinutes !== void 0) {
205
+ if (constraints.offsetMinutes < -720 || constraints.offsetMinutes > 840) {
206
+ throw new Error(`Invalid UTC offset: ${constraints.offsetMinutes} (must be -720 to +840)`);
207
+ }
208
+ }
209
+ if (constraints.periodCode === PERIOD_CUSTOM2 && !constraints.customSeconds) {
210
+ throw new Error("Custom period requires customSeconds");
211
+ }
212
+ }
213
+ if (constraints.vendorGroupId) {
214
+ if (!constraints.vendorGroupId.match(/^0x[a-fA-F0-9]{64}$/)) {
215
+ throw new Error(`Invalid vendorGroupId format: ${constraints.vendorGroupId}`);
216
+ }
217
+ flags |= FLAG_VENDOR_GROUP;
218
+ }
219
+ let leaf = encodePacked(
220
+ ["bytes4", "uint8", "uint8", "uint8"],
221
+ [DOMAIN_PREFIX2, TAG_COMPOUND_EMPLOYEE2, COMPOUND_LEAF_VERSION, flags]
222
+ );
223
+ if (flags & FLAG_ASSET) {
224
+ leaf = encodePacked(
225
+ ["bytes", "address"],
226
+ [leaf, constraints.allowedAsset]
227
+ );
228
+ }
229
+ if (flags & FLAG_RECIPIENT) {
230
+ leaf = encodePacked(
231
+ ["bytes", "address"],
232
+ [leaf, constraints.allowedRecipient]
233
+ );
234
+ }
235
+ if (flags & FLAG_CAP) {
236
+ const capBigEndian = toBigEndianUint128(constraints.maxAmount);
237
+ leaf = encodePacked(
238
+ ["bytes", "bytes"],
239
+ [leaf, capBigEndian]
240
+ );
241
+ }
242
+ if (flags & FLAG_DEADLINE) {
243
+ const deadlineBigEndian = toBigEndianUint48(constraints.deadline);
244
+ leaf = encodePacked(
245
+ ["bytes", "bytes"],
246
+ [leaf, deadlineBigEndian]
247
+ );
248
+ }
249
+ if (flags & FLAG_BUCKET) {
250
+ leaf = encodePacked(
251
+ ["bytes", "bytes32"],
252
+ [leaf, constraints.bucketId]
253
+ );
254
+ }
255
+ if (flags & FLAG_PERIOD) {
256
+ leaf = encodePacked(
257
+ ["bytes", "uint8"],
258
+ [leaf, constraints.periodCode]
259
+ );
260
+ const offset = constraints.offsetMinutes ?? 0;
261
+ const offsetBigEndian = toBigEndianInt16(offset);
262
+ leaf = encodePacked(
263
+ ["bytes", "bytes"],
264
+ [leaf, offsetBigEndian]
265
+ );
266
+ if (constraints.periodCode === PERIOD_CUSTOM2) {
267
+ const customSecondsBigEndian = toBigEndianUint32(constraints.customSeconds);
268
+ leaf = encodePacked(
269
+ ["bytes", "bytes"],
270
+ [leaf, customSecondsBigEndian]
271
+ );
272
+ }
273
+ }
274
+ if (flags & FLAG_VENDOR_GROUP) {
275
+ leaf = encodePacked(
276
+ ["bytes", "bytes32"],
277
+ [leaf, constraints.vendorGroupId]
278
+ );
279
+ }
280
+ return {
281
+ flags,
282
+ asset: constraints.allowedAsset,
283
+ recipient: constraints.allowedRecipient,
284
+ cap: constraints.maxAmount,
285
+ deadline: constraints.deadline,
286
+ bucketId: constraints.bucketId,
287
+ periodCode: constraints.periodCode,
288
+ offsetMinutes: constraints.offsetMinutes,
289
+ customSeconds: constraints.customSeconds,
290
+ vendorGroupId: constraints.vendorGroupId,
291
+ encoded: leaf
292
+ };
293
+ }
294
+ /**
295
+ * Create compound constraint policy
296
+ *
297
+ * High-level helper that builds compound leaf and returns everything needed
298
+ * for policy registration. Handles both single and multiple recipients.
299
+ */
300
+ createConstrainedPolicy(walletAddress, constraints) {
301
+ if (constraints.allowedRecipients && constraints.allowedRecipients.length > 1) {
302
+ throw new Error("Use createMultiRecipientPolicy() for multiple recipients");
303
+ }
304
+ const recipient = constraints.allowedRecipients?.[0] || constraints.allowedRecipient;
305
+ const normalizedConstraints = {
306
+ allowedAsset: constraints.allowedAsset,
307
+ allowedRecipient: recipient,
308
+ maxAmount: constraints.maxAmount,
309
+ deadline: constraints.deadline,
310
+ bucketId: constraints.bucketId,
311
+ // Week 1 additions
312
+ periodCode: constraints.periodCode,
313
+ offsetMinutes: constraints.offsetMinutes,
314
+ customSeconds: constraints.customSeconds,
315
+ vendorGroupId: constraints.vendorGroupId
316
+ };
317
+ const hasConstraints = normalizedConstraints.allowedAsset || normalizedConstraints.allowedRecipient || normalizedConstraints.maxAmount !== void 0 || normalizedConstraints.deadline !== void 0 || normalizedConstraints.bucketId || normalizedConstraints.periodCode !== void 0 || normalizedConstraints.vendorGroupId;
318
+ if (!hasConstraints) {
319
+ return {
320
+ policyId: keccak256(walletAddress),
321
+ merkleRoot: "0x0000000000000000000000000000000000000000000000000000000000000000",
322
+ leafAndProof: "0x",
323
+ // Empty bytes for no constraints
324
+ policyRootVersion: 1,
325
+ // Compound leaf version
326
+ leaf: {
327
+ flags: 0,
328
+ encoded: "0x"
329
+ }
330
+ };
331
+ }
332
+ const leaf = this.buildCompoundLeaf(normalizedConstraints);
333
+ const merkleRoot = keccak256(leaf.encoded);
334
+ return {
335
+ policyId: keccak256(walletAddress),
336
+ merkleRoot,
337
+ leafAndProof: leaf.encoded,
338
+ // Single leaf, no separate proof needed
339
+ policyRootVersion: 1,
340
+ // Compound leaf version
341
+ leaf
342
+ };
343
+ }
344
+ /**
345
+ * Build asset-only constraint (common case)
346
+ */
347
+ buildAssetConstraint(asset) {
348
+ return this.buildCompoundLeaf({ allowedAsset: asset });
349
+ }
350
+ /**
351
+ * Build recipient-only constraint (common case)
352
+ */
353
+ buildRecipientConstraint(recipient) {
354
+ return this.buildCompoundLeaf({ allowedRecipient: recipient });
355
+ }
356
+ /**
357
+ * Build cap-only constraint (common case)
358
+ */
359
+ buildCapConstraint(maxAmount) {
360
+ return this.buildCompoundLeaf({ maxAmount });
361
+ }
362
+ /**
363
+ * Build asset + recipient constraint (common case)
364
+ */
365
+ buildAssetRecipientConstraint(asset, recipient) {
366
+ return this.buildCompoundLeaf({
367
+ allowedAsset: asset,
368
+ allowedRecipient: recipient
369
+ });
370
+ }
371
+ /**
372
+ * Build recipient + cap constraint (common case)
373
+ */
374
+ buildRecipientCapConstraint(recipient, maxAmount) {
375
+ return this.buildCompoundLeaf({
376
+ allowedRecipient: recipient,
377
+ maxAmount
378
+ });
379
+ }
380
+ /**
381
+ * Build full constraint with all fields (common case)
382
+ */
383
+ buildFullConstraint(asset, recipient, maxAmount, deadline, bucketId) {
384
+ return this.buildCompoundLeaf({
385
+ allowedAsset: asset,
386
+ allowedRecipient: recipient,
387
+ maxAmount,
388
+ deadline,
389
+ bucketId
390
+ });
391
+ }
392
+ /**
393
+ * Create compound leaf with proper validation (alternative to buildCompoundLeaf)
394
+ *
395
+ * Provides a cleaner interface for creating individual compound leaves
396
+ */
397
+ createCompoundLeaf(constraints) {
398
+ if (!constraints.asset && !constraints.recipient && constraints.maxAmount === void 0 && constraints.deadline === void 0 && !constraints.bucketId) {
399
+ throw new Error("At least one constraint must be specified");
400
+ }
401
+ const policyConstraints = {
402
+ allowedAsset: constraints.asset,
403
+ allowedRecipient: constraints.recipient,
404
+ maxAmount: constraints.maxAmount,
405
+ deadline: constraints.deadline,
406
+ bucketId: constraints.bucketId
407
+ };
408
+ return this.buildCompoundLeaf(policyConstraints);
409
+ }
410
+ /**
411
+ * Build period constraint
412
+ */
413
+ buildPeriodConstraint(periodCode, offsetMinutes = 0, customSeconds) {
414
+ return this.buildCompoundLeaf({
415
+ periodCode,
416
+ offsetMinutes,
417
+ customSeconds
418
+ });
419
+ }
420
+ /**
421
+ * Build vendor group constraint
422
+ */
423
+ buildVendorGroupConstraint(vendorGroupId) {
424
+ return this.buildCompoundLeaf({ vendorGroupId });
425
+ }
426
+ /**
427
+ * Build period + cap constraint (common pattern)
428
+ */
429
+ buildPeriodCapConstraint(periodCode, maxAmount, offsetMinutes = 0) {
430
+ return this.buildCompoundLeaf({
431
+ periodCode,
432
+ offsetMinutes,
433
+ maxAmount
434
+ });
435
+ }
436
+ /**
437
+ * Build vendor group + cap + period constraint (enterprise pattern)
438
+ */
439
+ buildVendorGroupCapPeriodConstraint(vendorGroupId, maxAmount, periodCode, offsetMinutes = 0) {
440
+ return this.buildCompoundLeaf({
441
+ vendorGroupId,
442
+ maxAmount,
443
+ periodCode,
444
+ offsetMinutes
445
+ });
446
+ }
447
+ /**
448
+ * Generate vendor group ID from string (helper)
449
+ */
450
+ static generateVendorGroupId(name) {
451
+ return keccak256(encodePacked(["string"], [`VENDOR_GROUP_${name}`]));
452
+ }
453
+ /**
454
+ * Create multi-recipient policy with Merkle tree
455
+ *
456
+ * This creates a policy that supports multiple recipients by building a Merkle tree
457
+ * where each leaf represents one recipient constraint.
458
+ *
459
+ * Supports two call patterns:
460
+ * 1. Same constraints for all recipients: createMultiRecipientPolicy(wallet, PolicyConstraints)
461
+ * 2. Different constraints per recipient: createMultiRecipientPolicy(wallet, RecipientConstraint[])
462
+ */
463
+ createMultiRecipientPolicy(walletAddress, constraintsOrRecipients) {
464
+ let recipients;
465
+ let leaves;
466
+ if (Array.isArray(constraintsOrRecipients)) {
467
+ if (constraintsOrRecipients.length === 0) {
468
+ throw new Error("At least one recipient must be specified for multi-recipient policy");
469
+ }
470
+ const recipientAssetSet = /* @__PURE__ */ new Set();
471
+ for (const item of constraintsOrRecipients) {
472
+ const key = `${item.recipient.toLowerCase()}-${item.asset || "none"}`;
473
+ if (recipientAssetSet.has(key)) {
474
+ throw new Error(`Duplicate recipient-asset combination: ${item.recipient} with asset ${item.asset || "none"}`);
475
+ }
476
+ recipientAssetSet.add(key);
477
+ }
478
+ recipients = constraintsOrRecipients.map((item) => item.recipient);
479
+ leaves = constraintsOrRecipients.map((item) => {
480
+ const leafConstraints = {
481
+ allowedRecipient: item.recipient,
482
+ maxAmount: item.maxAmount,
483
+ deadline: item.deadline,
484
+ allowedAsset: item.asset
485
+ };
486
+ return this.buildCompoundLeaf(leafConstraints);
487
+ });
488
+ } else {
489
+ const constraints = constraintsOrRecipients;
490
+ recipients = constraints.allowedRecipients || (constraints.allowedRecipient ? [constraints.allowedRecipient] : []);
491
+ if (recipients.length === 0) {
492
+ throw new Error("At least one recipient must be specified for multi-recipient policy");
493
+ }
494
+ leaves = recipients.map((recipient) => {
495
+ const leafConstraints = {
496
+ allowedAsset: constraints.allowedAsset,
497
+ allowedRecipient: recipient,
498
+ maxAmount: constraints.maxAmount,
499
+ deadline: constraints.deadline,
500
+ bucketId: constraints.bucketId
501
+ };
502
+ return this.buildCompoundLeaf(leafConstraints);
503
+ });
504
+ }
505
+ const { merkleRoot, leafProofs } = this.buildMerkleTree(leaves, recipients);
506
+ return {
507
+ policyId: keccak256(walletAddress),
508
+ merkleRoot,
509
+ leaves,
510
+ leafProofs,
511
+ policyRootVersion: 1
512
+ };
513
+ }
514
+ /**
515
+ * Build Merkle tree from compound leaves
516
+ *
517
+ * Uses sorted pair hashing to match ConstraintLib.sol implementation
518
+ */
519
+ buildMerkleTree(leaves, recipients) {
520
+ if (leaves.length === 0) {
521
+ throw new Error("Cannot build Merkle tree with no leaves");
522
+ }
523
+ if (leaves.length === 1) {
524
+ const recipient = recipients?.[0] || leaves[0].recipient;
525
+ if (!recipient) {
526
+ throw new Error("Recipient must be specified for single leaf tree");
527
+ }
528
+ const asset = leaves[0].asset ? leaves[0].asset.toLowerCase() : "*";
529
+ const key = `${recipient.toLowerCase()}-${asset}`;
530
+ return {
531
+ merkleRoot: keccak256(leaves[0].encoded),
532
+ leafProofs: {
533
+ [key]: leaves[0].encoded
534
+ // No proof needed for single leaf
535
+ }
536
+ };
537
+ }
538
+ const leafHashes = leaves.map((leaf, index) => ({
539
+ hash: keccak256(leaf.encoded),
540
+ encoded: leaf.encoded,
541
+ originalIndex: index
542
+ }));
543
+ leafHashes.sort((a, b) => a.hash.localeCompare(b.hash));
544
+ const tree = [leafHashes.map((lh) => lh.hash)];
545
+ while (tree[tree.length - 1].length > 1) {
546
+ const currentLevel = tree[tree.length - 1];
547
+ const nextLevel = [];
548
+ for (let i = 0; i < currentLevel.length; i += 2) {
549
+ const left = currentLevel[i];
550
+ const right = i + 1 < currentLevel.length ? currentLevel[i + 1] : left;
551
+ const hash = left <= right ? keccak256(encodePacked(["bytes32", "bytes32"], [left, right])) : keccak256(encodePacked(["bytes32", "bytes32"], [right, left]));
552
+ nextLevel.push(hash);
553
+ }
554
+ tree.push(nextLevel);
555
+ }
556
+ const merkleRoot = tree[tree.length - 1][0];
557
+ const leafProofs = {};
558
+ for (let sortedIndex = 0; sortedIndex < leafHashes.length; sortedIndex++) {
559
+ const leafHash = leafHashes[sortedIndex];
560
+ const originalIndex = leafHash.originalIndex;
561
+ const proof = this.generateMerkleProof(tree, sortedIndex);
562
+ const leafAndProof = encodePacked(
563
+ ["bytes", "bytes"],
564
+ [leafHash.encoded, proof]
565
+ );
566
+ const recipient = recipients?.[originalIndex] || leaves[originalIndex].recipient;
567
+ if (!recipient) {
568
+ throw new Error(`Recipient must be specified for leaf ${originalIndex}`);
569
+ }
570
+ const asset = leaves[originalIndex].asset ? leaves[originalIndex].asset.toLowerCase() : "*";
571
+ const key = `${recipient.toLowerCase()}-${asset}`;
572
+ leafProofs[key] = leafAndProof;
573
+ }
574
+ return {
575
+ merkleRoot,
576
+ leafProofs,
577
+ tree: { root: merkleRoot, leaves: leafHashes }
578
+ };
579
+ }
580
+ /**
581
+ * Generate Merkle proof for a leaf at given index
582
+ */
583
+ generateMerkleProof(tree, leafIndex) {
584
+ let proof = "0x";
585
+ let currentIndex = leafIndex;
586
+ for (let level = 0; level < tree.length - 1; level++) {
587
+ const currentLevel = tree[level];
588
+ const isRightNode = currentIndex % 2 === 1;
589
+ let siblingIndex;
590
+ if (isRightNode) {
591
+ siblingIndex = currentIndex - 1;
592
+ } else {
593
+ siblingIndex = currentIndex + 1;
594
+ if (siblingIndex >= currentLevel.length) {
595
+ siblingIndex = currentIndex;
596
+ }
597
+ }
598
+ const sibling = currentLevel[siblingIndex];
599
+ proof = encodePacked(["bytes", "bytes32"], [proof, sibling]);
600
+ currentIndex = Math.floor(currentIndex / 2);
601
+ }
602
+ return proof;
603
+ }
604
+ /**
605
+ * Generate proof for a leaf at specific index (alternative interface)
606
+ */
607
+ generateProof(tree, leafIndex) {
608
+ const hashes = tree.leaves.map((l) => keccak256(l.encoded));
609
+ const treeStructure = [hashes];
610
+ while (treeStructure[treeStructure.length - 1].length > 1) {
611
+ const currentLevel = treeStructure[treeStructure.length - 1];
612
+ const nextLevel = [];
613
+ for (let i = 0; i < currentLevel.length; i += 2) {
614
+ const left = currentLevel[i];
615
+ const right = i + 1 < currentLevel.length ? currentLevel[i + 1] : left;
616
+ const hash = left <= right ? keccak256(encodePacked(["bytes32", "bytes32"], [left, right])) : keccak256(encodePacked(["bytes32", "bytes32"], [right, left]));
617
+ nextLevel.push(hash);
618
+ }
619
+ treeStructure.push(nextLevel);
620
+ }
621
+ const proof = [];
622
+ let currentIndex = leafIndex;
623
+ for (let level = 0; level < treeStructure.length - 1; level++) {
624
+ const currentLevel = treeStructure[level];
625
+ const isRightNode = currentIndex % 2 === 1;
626
+ let siblingIndex;
627
+ if (isRightNode) {
628
+ siblingIndex = currentIndex - 1;
629
+ } else {
630
+ siblingIndex = currentIndex + 1;
631
+ if (siblingIndex >= currentLevel.length) {
632
+ siblingIndex = currentIndex;
633
+ }
634
+ }
635
+ proof.push(currentLevel[siblingIndex]);
636
+ currentIndex = Math.floor(currentIndex / 2);
637
+ }
638
+ return proof;
639
+ }
640
+ /**
641
+ * Verify a Merkle proof
642
+ */
643
+ verifyProof(root, leafData, proof) {
644
+ let computedHash = keccak256(leafData);
645
+ for (const sibling of proof) {
646
+ computedHash = computedHash <= sibling ? keccak256(encodePacked(["bytes32", "bytes32"], [computedHash, sibling])) : keccak256(encodePacked(["bytes32", "bytes32"], [sibling, computedHash]));
647
+ }
648
+ return computedHash === root;
649
+ }
650
+ /**
651
+ * Build vendor group with period budget constraint (common pattern)
652
+ *
653
+ * Creates a vendor group with shared period budget across authorized members.
654
+ *
655
+ * @param vendorGroupId Vendor group identifier
656
+ * @param maxAmount Shared budget amount for the period
657
+ * @param periodCode Period type (PERIOD_DAILY, PERIOD_WEEKLY, etc.)
658
+ * @param offsetMinutes UTC timezone offset (default: 0)
659
+ * @returns Compound leaf with vendor + period constraints
660
+ */
661
+ buildVendorGroupPeriodConstraint(vendorGroupId, maxAmount, periodCode, offsetMinutes = 0) {
662
+ return this.buildCompoundLeaf({
663
+ vendorGroupId,
664
+ maxAmount,
665
+ periodCode,
666
+ offsetMinutes
667
+ });
668
+ }
669
+ };
670
+ CompoundLeafV3Builder = class {
671
+ /**
672
+ * Build V3 compound constraint leaf with venue controls
673
+ *
674
+ * Format: [4B domain_v3][1B tag][1B version][2B flags][conditional_fields...]
675
+ */
676
+ buildVenueConstraintLeaf(constraints) {
677
+ let flags = 0;
678
+ const parts = [];
679
+ parts.push(DOMAIN_V3);
680
+ parts.push(encodePacked(["uint8"], [TAG_COMPOUND_V3]));
681
+ parts.push(encodePacked(["uint8"], [VERSION_V3]));
682
+ if (constraints.allowedTarget) {
683
+ if (!constraints.allowedTarget.match(/^0x[a-fA-F0-9]{40}$/)) {
684
+ throw new Error(`Invalid target address: ${constraints.allowedTarget}`);
685
+ }
686
+ flags |= FLAG_TARGET;
687
+ }
688
+ if (constraints.allowedSelectors && constraints.allowedSelectors.length > 0) {
689
+ if (constraints.allowedSelectors.length > 8) {
690
+ throw new Error("Too many selectors (max 8)");
691
+ }
692
+ for (const selector of constraints.allowedSelectors) {
693
+ if (!selector.match(/^0x[a-fA-F0-9]{8}$/)) {
694
+ throw new Error(`Invalid selector format: ${selector}`);
695
+ }
696
+ }
697
+ flags |= FLAG_SELECTOR_LIST;
698
+ }
699
+ if (constraints.bridgeBlocked) {
700
+ flags |= FLAG_NO_BRIDGE;
701
+ }
702
+ parts.push(toBigEndianUint16(flags));
703
+ if (flags & FLAG_TARGET) {
704
+ parts.push(constraints.allowedTarget);
705
+ }
706
+ if (flags & FLAG_SELECTOR_LIST) {
707
+ parts.push(encodePacked(["uint8"], [constraints.allowedSelectors.length]));
708
+ for (const selector of constraints.allowedSelectors) {
709
+ parts.push(selector);
710
+ }
711
+ }
712
+ const encoded = encodePacked(
713
+ parts.map(() => "bytes"),
714
+ parts
715
+ );
716
+ return {
717
+ flags,
718
+ venueConstraints: {
719
+ allowedTarget: constraints.allowedTarget,
720
+ allowedSelectors: constraints.allowedSelectors,
721
+ bridgeBlocked: constraints.bridgeBlocked
722
+ },
723
+ asset: constraints.allowedAsset,
724
+ recipient: constraints.allowedRecipient,
725
+ cap: constraints.maxAmount,
726
+ deadline: constraints.deadline,
727
+ bucketId: constraints.bucketId,
728
+ periodCode: constraints.periodCode,
729
+ offsetMinutes: constraints.offsetMinutes,
730
+ customSeconds: constraints.customSeconds,
731
+ vendorGroupId: constraints.vendorGroupId,
732
+ encoded
733
+ };
734
+ }
735
+ /**
736
+ * Create a simple V3 policy with venue controls
737
+ */
738
+ createVenueConstrainedPolicy(walletAddress, constraints) {
739
+ const leaf = this.buildVenueConstraintLeaf(constraints);
740
+ const merkleRoot = keccak256(leaf.encoded);
741
+ const leafAndProof = leaf.encoded;
742
+ const recipient = constraints.allowedRecipient || "0x0000000000000000000000000000000000000000";
743
+ const recipientKey = recipient.toLowerCase();
744
+ const policy = {
745
+ policyId: keccak256(encodePacked(["string"], [`V3_VENUE_POLICY_${Date.now()}_${Math.random()}`])),
746
+ merkleRoot,
747
+ leaves: [leaf],
748
+ leafProofs: {
749
+ [recipientKey]: leafAndProof
750
+ },
751
+ policyRootVersion: 1
752
+ };
753
+ return Object.assign(policy, {
754
+ getLeafAndProofForRecipient: (targetRecipient) => {
755
+ if (targetRecipient) {
756
+ const key = targetRecipient.toLowerCase();
757
+ return policy.leafProofs[key] || leafAndProof;
758
+ }
759
+ return leafAndProof;
760
+ }
761
+ });
762
+ }
763
+ };
764
+ }
765
+ });
766
+
767
+ // src/constraints/agentConstraintBuilder.ts
768
+ import { keccak256 as keccak2562, parseEther } from "viem";
769
+
770
+ // src/policy/types.ts
771
+ var V2_FLAG_RECIPIENT = 1;
772
+ var V2_FLAG_CAP = 2;
773
+ var V2_FLAG_DEADLINE = 4;
774
+ var V2_FLAG_ASSET = 8;
775
+ var V2_FLAG_BUCKET = 16;
776
+ var V2_FLAG_PERIOD = 32;
777
+ var V2_FLAG_VENDOR_GROUP = 64;
778
+ var PERIOD_NONE = 0;
779
+ var PERIOD_DAILY = 1;
780
+ var PERIOD_WEEKLY = 2;
781
+ var PERIOD_MONTH30 = 3;
782
+ var PERIOD_CUSTOM = 4;
783
+ var GLOBAL_FLAG_NO_BRIDGE = 1n << 0n;
784
+ var GLOBAL_FLAG_POST_CONDITIONS = 1n << 1n;
785
+ var GLOBAL_FLAG_FX_SAFETY = 1n << 2n;
786
+ var GLOBAL_FLAG_SOLVER_ENVELOPE = 1n << 3n;
787
+
788
+ // src/policy/v2LeafBuilder.ts
789
+ var DOMAIN_PREFIX = "0x1a13d438";
790
+ var TAG_COMPOUND_EMPLOYEE = 16;
791
+ var VERSION = 1;
792
+ function toBigEndianHex(value, byteLength) {
793
+ const hex = BigInt(value).toString(16).padStart(byteLength * 2, "0");
794
+ if (hex.length > byteLength * 2) {
795
+ throw new Error(`Value ${value} exceeds ${byteLength} bytes`);
796
+ }
797
+ return hex;
798
+ }
799
+ function validateAddress(address, fieldName) {
800
+ if (!address.startsWith("0x") || address.length !== 42) {
801
+ throw new Error(`${fieldName} must be a valid 20-byte address, got: ${address}`);
802
+ }
803
+ }
804
+ function validateBytes32(value, fieldName) {
805
+ if (!value.startsWith("0x") || value.length !== 66) {
806
+ throw new Error(`${fieldName} must be a valid 32-byte hex, got length ${value.length}`);
807
+ }
808
+ }
809
+ function buildV2CompoundLeaf(params) {
810
+ const chunks = [];
811
+ chunks.push(DOMAIN_PREFIX.slice(2));
812
+ chunks.push(TAG_COMPOUND_EMPLOYEE.toString(16).padStart(2, "0"));
813
+ chunks.push(VERSION.toString(16).padStart(2, "0"));
814
+ if (params.flags < 0 || params.flags > 255) {
815
+ throw new Error(`Flags must be 0-255, got: ${params.flags}`);
816
+ }
817
+ chunks.push(params.flags.toString(16).padStart(2, "0"));
818
+ if (params.flags & V2_FLAG_ASSET) {
819
+ if (!params.asset) {
820
+ throw new Error("asset is required when FLAG_ASSET is set");
821
+ }
822
+ validateAddress(params.asset, "asset");
823
+ chunks.push(params.asset.slice(2).toLowerCase());
824
+ }
825
+ if (params.flags & V2_FLAG_RECIPIENT) {
826
+ if (!params.allowedRecipient) {
827
+ throw new Error("allowedRecipient is required when FLAG_RECIPIENT is set");
828
+ }
829
+ validateAddress(params.allowedRecipient, "allowedRecipient");
830
+ chunks.push(params.allowedRecipient.slice(2).toLowerCase());
831
+ }
832
+ if (params.flags & V2_FLAG_CAP) {
833
+ if (params.cap === void 0) {
834
+ throw new Error("cap is required when FLAG_CAP is set");
835
+ }
836
+ const maxUint128 = (1n << 128n) - 1n;
837
+ if (params.cap < 0n || params.cap > maxUint128) {
838
+ throw new Error(`cap must be 0 to ${maxUint128}, got: ${params.cap}`);
839
+ }
840
+ chunks.push(toBigEndianHex(params.cap, 16));
841
+ }
842
+ if (params.flags & V2_FLAG_DEADLINE) {
843
+ if (params.deadline === void 0) {
844
+ throw new Error("deadline is required when FLAG_DEADLINE is set");
845
+ }
846
+ const maxUint48 = (1n << 48n) - 1n;
847
+ if (BigInt(params.deadline) < 0n || BigInt(params.deadline) > maxUint48) {
848
+ throw new Error(`deadline must be 0 to ${maxUint48}, got: ${params.deadline}`);
849
+ }
850
+ chunks.push(toBigEndianHex(params.deadline, 6));
851
+ }
852
+ if (params.flags & V2_FLAG_BUCKET) {
853
+ if (!params.bucketId) {
854
+ throw new Error("bucketId is required when FLAG_BUCKET is set");
855
+ }
856
+ validateBytes32(params.bucketId, "bucketId");
857
+ chunks.push(params.bucketId.slice(2).toLowerCase());
858
+ }
859
+ if (params.flags & V2_FLAG_PERIOD) {
860
+ if (params.periodCode === void 0) {
861
+ throw new Error("periodCode is required when FLAG_PERIOD is set");
862
+ }
863
+ if (params.periodCode < 0 || params.periodCode > 255) {
864
+ throw new Error(`periodCode must be 0-255, got: ${params.periodCode}`);
865
+ }
866
+ chunks.push(params.periodCode.toString(16).padStart(2, "0"));
867
+ const offsetMinutes = params.offsetMinutes ?? 0;
868
+ if (offsetMinutes < -32768 || offsetMinutes > 32767) {
869
+ throw new Error(`offsetMinutes must be -32768 to 32767, got: ${offsetMinutes}`);
870
+ }
871
+ const unsignedOffset = offsetMinutes < 0 ? 65536 + offsetMinutes : offsetMinutes;
872
+ chunks.push(unsignedOffset.toString(16).padStart(4, "0"));
873
+ if (params.periodCode === PERIOD_CUSTOM) {
874
+ if (params.customSeconds === void 0) {
875
+ throw new Error("customSeconds is required when periodCode is PERIOD_CUSTOM");
876
+ }
877
+ const maxUint32 = 4294967295;
878
+ if (params.customSeconds < 0 || params.customSeconds > maxUint32) {
879
+ throw new Error(`customSeconds must be 0 to ${maxUint32}, got: ${params.customSeconds}`);
880
+ }
881
+ chunks.push(params.customSeconds.toString(16).padStart(8, "0"));
882
+ }
883
+ }
884
+ if (params.flags & V2_FLAG_VENDOR_GROUP) {
885
+ if (!params.vendorGroupId) {
886
+ throw new Error("vendorGroupId is required when FLAG_VENDOR_GROUP is set");
887
+ }
888
+ validateBytes32(params.vendorGroupId, "vendorGroupId");
889
+ chunks.push(params.vendorGroupId.slice(2).toLowerCase());
890
+ }
891
+ return `0x${chunks.join("")}`;
892
+ }
893
+ function v2ConstraintsToLeafParams(params) {
894
+ let flags = 0;
895
+ if (params.allowedRecipient) {
896
+ flags |= V2_FLAG_RECIPIENT;
897
+ }
898
+ if (params.cap !== void 0) {
899
+ flags |= V2_FLAG_CAP;
900
+ }
901
+ if (params.deadline !== void 0) {
902
+ flags |= V2_FLAG_DEADLINE;
903
+ }
904
+ if (params.asset) {
905
+ flags |= V2_FLAG_ASSET;
906
+ }
907
+ if (params.periodType && params.periodType !== "none") {
908
+ flags |= V2_FLAG_PERIOD;
909
+ }
910
+ if (params.vendorGroupId) {
911
+ flags |= V2_FLAG_VENDOR_GROUP;
912
+ }
913
+ let periodCode;
914
+ if (params.periodType) {
915
+ switch (params.periodType) {
916
+ case "none":
917
+ periodCode = 0;
918
+ break;
919
+ case "daily":
920
+ periodCode = 1;
921
+ break;
922
+ case "weekly":
923
+ periodCode = 2;
924
+ break;
925
+ case "monthly":
926
+ periodCode = 3;
927
+ break;
928
+ case "custom":
929
+ periodCode = 4;
930
+ break;
931
+ }
932
+ }
933
+ return {
934
+ flags,
935
+ allowedRecipient: params.allowedRecipient,
936
+ cap: params.cap,
937
+ deadline: params.deadline,
938
+ asset: params.asset,
939
+ periodCode,
940
+ offsetMinutes: params.utcOffsetMinutes,
941
+ customSeconds: params.customPeriodSeconds,
942
+ vendorGroupId: params.vendorGroupId
943
+ };
944
+ }
945
+ function buildV2LeafFromConstraints(params) {
946
+ const leafParams = v2ConstraintsToLeafParams(params);
947
+ return buildV2CompoundLeaf(leafParams);
948
+ }
949
+
950
+ // src/constraints/agentConstraintBuilder.ts
951
+ init_constraints();
952
+ function buildV2ConstraintsFromAgent(constraints) {
953
+ if (constraints.allowedRecipients && constraints.allowedRecipients.length > 1) {
954
+ return buildMultiRecipientV2Constraints(constraints);
955
+ }
956
+ const v2Params = {};
957
+ if (constraints.allowedRecipients && constraints.allowedRecipients.length === 1) {
958
+ v2Params.allowedRecipient = constraints.allowedRecipients[0];
959
+ }
960
+ if (constraints.maxDailyUsd) {
961
+ v2Params.cap = parseEther(String(constraints.maxDailyUsd));
962
+ v2Params.periodType = "daily";
963
+ } else if (constraints.maxPerTxUsd) {
964
+ v2Params.cap = parseEther(String(constraints.maxPerTxUsd));
965
+ }
966
+ if (constraints.deadline) {
967
+ v2Params.deadline = constraints.deadline;
968
+ }
969
+ if (constraints.allowedAssets && constraints.allowedAssets.length > 0) {
970
+ v2Params.asset = constraints.allowedAssets[0];
971
+ }
972
+ if (constraints.vendorGroupId !== void 0) {
973
+ v2Params.vendorGroupId = bigintToBytes32(constraints.vendorGroupId);
974
+ }
975
+ const leaf = buildV2LeafFromConstraints(v2Params);
976
+ const root = keccak2562(leaf);
977
+ let recipientLeaves;
978
+ if (constraints.allowedRecipients && constraints.allowedRecipients.length === 1) {
979
+ const recipient = constraints.allowedRecipients[0].toLowerCase();
980
+ const asset = constraints.allowedAssets?.[0] ? constraints.allowedAssets[0].toLowerCase() : "*";
981
+ const key = `${recipient}-${asset}`;
982
+ recipientLeaves = { [key]: leaf };
983
+ }
984
+ return { leaf, root, recipientLeaves };
985
+ }
986
+ function buildMultiRecipientV2Constraints(constraints) {
987
+ const recipients = constraints.allowedRecipients;
988
+ const builder = new CompoundLeafBuilder();
989
+ const cap = constraints.maxDailyUsd ? parseEther(String(constraints.maxDailyUsd)) : constraints.maxPerTxUsd ? parseEther(String(constraints.maxPerTxUsd)) : void 0;
990
+ const dummyWallet = "0x0000000000000000000000000000000000000001";
991
+ const assets = constraints.allowedAssets;
992
+ const hasMultipleAssets = assets && assets.length > 1;
993
+ let multiPolicy;
994
+ if (hasMultipleAssets) {
995
+ const recipientAssetCombinations = [];
996
+ for (const recipient of recipients) {
997
+ for (const asset of assets) {
998
+ recipientAssetCombinations.push({
999
+ recipient,
1000
+ asset,
1001
+ maxAmount: cap,
1002
+ deadline: constraints.deadline
1003
+ });
1004
+ }
1005
+ }
1006
+ multiPolicy = builder.createMultiRecipientPolicy(dummyWallet, recipientAssetCombinations);
1007
+ } else {
1008
+ const asset = assets?.[0];
1009
+ multiPolicy = builder.createMultiRecipientPolicy(dummyWallet, {
1010
+ allowedRecipients: recipients,
1011
+ allowedAsset: asset,
1012
+ maxAmount: cap,
1013
+ deadline: constraints.deadline,
1014
+ periodCode: constraints.maxDailyUsd ? PERIOD_DAILY2 : void 0
1015
+ });
1016
+ }
1017
+ const defaultAsset = assets?.[0] ? assets[0].toLowerCase() : "*";
1018
+ const defaultKey = `${recipients[0].toLowerCase()}-${defaultAsset}`;
1019
+ const defaultLeafAndProof = multiPolicy.leafProofs[defaultKey];
1020
+ if (!defaultLeafAndProof) {
1021
+ throw new Error(`Failed to get default leaf+proof for multi-recipient policy`);
1022
+ }
1023
+ return {
1024
+ leaf: defaultLeafAndProof,
1025
+ // This is actually leafAndProof (leaf + merkle proof)
1026
+ root: multiPolicy.merkleRoot,
1027
+ recipientLeaves: multiPolicy.leafProofs
1028
+ // Map of recipient-asset -> leafAndProof
1029
+ };
1030
+ }
1031
+ function constraintsToV2Params(constraints, recipient) {
1032
+ const params = {};
1033
+ if (recipient) {
1034
+ params.allowedRecipient = recipient;
1035
+ } else if (constraints.allowedRecipients && constraints.allowedRecipients.length === 1) {
1036
+ params.allowedRecipient = constraints.allowedRecipients[0];
1037
+ }
1038
+ if (constraints.maxDailyUsd) {
1039
+ params.cap = parseEther(String(constraints.maxDailyUsd));
1040
+ params.periodType = "daily";
1041
+ } else if (constraints.maxPerTxUsd) {
1042
+ params.cap = parseEther(String(constraints.maxPerTxUsd));
1043
+ }
1044
+ if (constraints.deadline) {
1045
+ params.deadline = constraints.deadline;
1046
+ }
1047
+ if (constraints.allowedAssets && constraints.allowedAssets.length > 0) {
1048
+ params.asset = constraints.allowedAssets[0];
1049
+ }
1050
+ if (constraints.vendorGroupId !== void 0) {
1051
+ params.vendorGroupId = bigintToBytes32(constraints.vendorGroupId);
1052
+ }
1053
+ return params;
1054
+ }
1055
+ function bigintToBytes32(value) {
1056
+ return `0x${value.toString(16).padStart(64, "0")}`;
1057
+ }
1058
+
1059
+ export {
1060
+ FLAG_RECIPIENT,
1061
+ FLAG_CAP,
1062
+ FLAG_DEADLINE,
1063
+ FLAG_ASSET,
1064
+ FLAG_BUCKET,
1065
+ FLAG_PERIOD,
1066
+ FLAG_VENDOR_GROUP,
1067
+ DOMAIN_V3,
1068
+ VERSION_V3,
1069
+ TAG_COMPOUND_V3,
1070
+ FLAG_TARGET,
1071
+ FLAG_SELECTOR_LIST,
1072
+ FLAG_NO_BRIDGE,
1073
+ FLAG_OPS_HASH,
1074
+ PERIOD_NONE2 as PERIOD_NONE,
1075
+ PERIOD_DAILY2 as PERIOD_DAILY,
1076
+ PERIOD_WEEKLY2 as PERIOD_WEEKLY,
1077
+ PERIOD_MONTH302 as PERIOD_MONTH30,
1078
+ PERIOD_CUSTOM2 as PERIOD_CUSTOM,
1079
+ CompoundLeafBuilder,
1080
+ createConstraintBuilder,
1081
+ getLeafAndProofForRecipient,
1082
+ isRecipientAllowed,
1083
+ buildConstraintCalldata,
1084
+ buildConstraintCalldataFromIntent,
1085
+ extractConstraintDataFromOperations,
1086
+ CompoundLeafV3Builder,
1087
+ init_constraints,
1088
+ V2_FLAG_RECIPIENT,
1089
+ V2_FLAG_CAP,
1090
+ V2_FLAG_DEADLINE,
1091
+ V2_FLAG_ASSET,
1092
+ V2_FLAG_BUCKET,
1093
+ V2_FLAG_PERIOD,
1094
+ V2_FLAG_VENDOR_GROUP,
1095
+ PERIOD_NONE as PERIOD_NONE2,
1096
+ PERIOD_DAILY as PERIOD_DAILY2,
1097
+ PERIOD_WEEKLY as PERIOD_WEEKLY2,
1098
+ PERIOD_MONTH30 as PERIOD_MONTH302,
1099
+ PERIOD_CUSTOM as PERIOD_CUSTOM2,
1100
+ GLOBAL_FLAG_NO_BRIDGE,
1101
+ GLOBAL_FLAG_POST_CONDITIONS,
1102
+ GLOBAL_FLAG_FX_SAFETY,
1103
+ GLOBAL_FLAG_SOLVER_ENVELOPE,
1104
+ DOMAIN_PREFIX,
1105
+ TAG_COMPOUND_EMPLOYEE,
1106
+ VERSION,
1107
+ buildV2CompoundLeaf,
1108
+ v2ConstraintsToLeafParams,
1109
+ buildV2LeafFromConstraints,
1110
+ buildV2ConstraintsFromAgent,
1111
+ constraintsToV2Params
1112
+ };