@getpara/shared 1.29.0 → 1.31.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.
@@ -1,5 +1,6 @@
1
1
  import { z } from 'zod';
2
- export const policyAuthoringSigningWalletTypes = ['EVM'];
2
+ import { permissionsV2UserParameterSaveSchema, permissionsV2UserParameterViewSchema, } from './permissionsV2UserParameters.js';
3
+ export const policyAuthoringSigningWalletTypes = ['EVM', 'SOLANA', 'COSMOS', 'STELLAR', 'SUI'];
3
4
  export const policyAuthoringSigningRequestRoutes = [
4
5
  'evm.sign_transaction',
5
6
  'evm.sign_raw',
@@ -7,6 +8,10 @@ export const policyAuthoringSigningRequestRoutes = [
7
8
  'evm.sign_authorization',
8
9
  'evm.sign_message',
9
10
  'smart_account.user_operation',
11
+ 'solana.sign_transaction',
12
+ 'cosmos.sign_transaction',
13
+ 'stellar.sign_transaction',
14
+ 'sui.sign_transaction',
10
15
  ];
11
16
  export const permissionsV2SigningRequestTypes = [
12
17
  'evm_transaction',
@@ -15,8 +20,20 @@ export const permissionsV2SigningRequestTypes = [
15
20
  'evm_typed_data',
16
21
  'evm_authorization',
17
22
  'smart_account_user_operation',
23
+ 'solana_transaction',
24
+ 'cosmos_transaction',
25
+ 'cosmos_message',
26
+ 'stellar_transaction',
27
+ 'sui_transaction',
28
+ 'raw_message',
18
29
  ];
19
30
  const nonEmptyStringSchema = z.string().min(1);
31
+ export const permissionsV2ParameterDeclarationSchema = z
32
+ .object({
33
+ id: nonEmptyStringSchema,
34
+ label: nonEmptyStringSchema,
35
+ })
36
+ .strict();
20
37
  const uniqueNonEmptyStringsSchema = z
21
38
  .array(nonEmptyStringSchema)
22
39
  .min(1)
@@ -48,6 +65,7 @@ export const permissionsV2ConditionSchema = z.lazy(() => z.discriminatedUnion('k
48
65
  fact: nonEmptyStringSchema,
49
66
  op: permissionsV2CompareOperatorSchema,
50
67
  value: policyAuthoringJsonValueSchema,
68
+ parameter: permissionsV2ParameterDeclarationSchema.optional(),
51
69
  })
52
70
  .strict(),
53
71
  z
@@ -58,6 +76,7 @@ export const permissionsV2ConditionSchema = z.lazy(() => z.discriminatedUnion('k
58
76
  value: nonEmptyStringSchema,
59
77
  window: nonEmptyStringSchema,
60
78
  asset: nonEmptyStringSchema.optional(),
79
+ parameter: permissionsV2ParameterDeclarationSchema.optional(),
61
80
  })
62
81
  .strict(),
63
82
  z
@@ -79,7 +98,7 @@ export const permissionsV2ConditionSchema = z.lazy(() => z.discriminatedUnion('k
79
98
  })
80
99
  .strict(),
81
100
  ]));
82
- export const permissionsV2PartnerAuthoredPolicySelectorSchema = z
101
+ const permissionsV2PartnerAuthoredPolicySelectorObjectSchema = z
83
102
  .object({
84
103
  walletId: nonEmptyStringSchema.optional(),
85
104
  chainId: z.union([nonEmptyStringSchema, uniqueNonEmptyStringsSchema]).optional(),
@@ -88,6 +107,7 @@ export const permissionsV2PartnerAuthoredPolicySelectorSchema = z
88
107
  requestType: permissionsV2SigningRequestTypeSchema.optional(),
89
108
  })
90
109
  .strict();
110
+ export const permissionsV2PartnerAuthoredPolicySelectorSchema = permissionsV2PartnerAuthoredPolicySelectorObjectSchema;
91
111
  export const permissionsV2PolicyMetadataSchema = z
92
112
  .object({
93
113
  label: z.string().optional(),
@@ -99,19 +119,544 @@ export const permissionsV2PolicyMetadataSchema = z
99
119
  export const permissionsV2PartnerPolicyMetadataSchema = permissionsV2PolicyMetadataSchema.extend({
100
120
  productMode: permissionsV2PolicyModeSchema,
101
121
  });
122
+ const conditionalApprovalNameSchema = z
123
+ .string()
124
+ .trim()
125
+ .min(1)
126
+ .max(64)
127
+ .refine((value) => value === value.normalize('NFKC'), {
128
+ message: 'names must use normalized Unicode',
129
+ });
130
+ const conditionalApprovalIdentifierSchema = z.string().trim().min(1).max(64);
131
+ const conditionalApprovalActorIdSchema = z.string().trim().min(1).max(128);
132
+ const conditionalApprovalRequestIdSchema = z.string().trim().min(1).max(256);
133
+ export const permissionsV2ConditionalApprovalEligibilitySchema = z.union([
134
+ z
135
+ .object({
136
+ kind: z.literal('role'),
137
+ name: conditionalApprovalNameSchema,
138
+ })
139
+ .strict(),
140
+ z
141
+ .object({
142
+ kind: z.literal('attribute'),
143
+ name: conditionalApprovalNameSchema,
144
+ operator: z.literal('eq'),
145
+ value: conditionalApprovalNameSchema,
146
+ })
147
+ .strict(),
148
+ z
149
+ .object({
150
+ kind: z.literal('attribute'),
151
+ name: conditionalApprovalNameSchema,
152
+ operator: z.literal('in'),
153
+ values: z
154
+ .array(conditionalApprovalNameSchema)
155
+ .min(1)
156
+ .refine((values) => new Set(values).size === values.length, {
157
+ message: 'attribute values must be unique',
158
+ }),
159
+ })
160
+ .strict(),
161
+ ]);
162
+ const conditionalApprovalEligibilityListSchema = z
163
+ .array(permissionsV2ConditionalApprovalEligibilitySchema)
164
+ .min(1)
165
+ .max(10)
166
+ .refine((eligibility) => new Set(eligibility.map((clause) => JSON.stringify(clause))).size === eligibility.length, {
167
+ message: 'eligibility clauses must be unique',
168
+ });
169
+ export const permissionsV2ConditionalApprovalStageSchema = z
170
+ .object({
171
+ id: conditionalApprovalIdentifierSchema,
172
+ requiredApprovals: z.union([z.number().int().min(1).max(25), z.literal('all')]),
173
+ eligibility: conditionalApprovalEligibilityListSchema,
174
+ minimumAmount: z
175
+ .string()
176
+ .regex(/^(0|[1-9][0-9]*)$/)
177
+ .optional(),
178
+ })
179
+ .strict();
180
+ const conditionalApprovalRequiredCountKnobSchema = z
181
+ .object({
182
+ id: conditionalApprovalIdentifierSchema,
183
+ kind: z.literal('required_approvals'),
184
+ stageId: conditionalApprovalIdentifierSchema,
185
+ min: z.number().int().min(1).max(25),
186
+ max: z.number().int().min(1).max(25),
187
+ })
188
+ .strict()
189
+ .refine((knob) => knob.min <= knob.max, { message: 'minimum required approvals must not exceed maximum' });
190
+ const conditionalApprovalEligibleGroupOptionSchema = z
191
+ .object({
192
+ id: conditionalApprovalIdentifierSchema,
193
+ eligibility: conditionalApprovalEligibilityListSchema,
194
+ })
195
+ .strict();
196
+ const conditionalApprovalEligibleGroupKnobSchema = z
197
+ .object({
198
+ id: conditionalApprovalIdentifierSchema,
199
+ kind: z.literal('eligible_group'),
200
+ stageId: conditionalApprovalIdentifierSchema,
201
+ defaultOptionId: conditionalApprovalIdentifierSchema,
202
+ options: z
203
+ .array(conditionalApprovalEligibleGroupOptionSchema)
204
+ .min(1)
205
+ .max(25)
206
+ .refine((options) => new Set(options.map((option) => option.id)).size === options.length, {
207
+ message: 'eligible group option identifiers must be unique',
208
+ }),
209
+ })
210
+ .strict();
211
+ export const permissionsV2ConditionalApprovalSafeKnobSchema = z.union([
212
+ conditionalApprovalRequiredCountKnobSchema,
213
+ conditionalApprovalEligibleGroupKnobSchema,
214
+ z
215
+ .object({
216
+ id: conditionalApprovalIdentifierSchema,
217
+ kind: z.literal('minimum_amount'),
218
+ stageId: conditionalApprovalIdentifierSchema,
219
+ })
220
+ .strict(),
221
+ ]);
222
+ export const permissionsV2ConditionalApprovalRequirementSchema = z
223
+ .object({
224
+ id: conditionalApprovalIdentifierSchema,
225
+ evidence: z.enum(['authenticated_approval', 'transaction_signature']).optional(),
226
+ amountFact: z.enum(['request.value.baseUnits', 'request.token.value.baseUnits']).optional(),
227
+ stages: z
228
+ .array(permissionsV2ConditionalApprovalStageSchema)
229
+ .min(1)
230
+ .max(5)
231
+ .refine((stages) => new Set(stages.map((stage) => stage.id)).size === stages.length, {
232
+ message: 'stage identifiers must be unique',
233
+ }),
234
+ configurationManagerEligibility: conditionalApprovalEligibilityListSchema.optional(),
235
+ safeKnobs: z
236
+ .array(permissionsV2ConditionalApprovalSafeKnobSchema)
237
+ .min(1)
238
+ .refine((knobs) => new Set(knobs.map((knob) => knob.id)).size === knobs.length, {
239
+ message: 'safe knob identifiers must be unique',
240
+ })
241
+ .optional(),
242
+ })
243
+ .strict()
244
+ .superRefine((requirement, context) => {
245
+ const stagesById = new Map(requirement.stages.map((stage) => [stage.id, stage]));
246
+ const configuredStageIds = new Set();
247
+ const hasBands = requirement.stages.some((stage) => stage.minimumAmount !== undefined);
248
+ if (hasBands !== (requirement.amountFact !== undefined)) {
249
+ context.addIssue({
250
+ code: z.ZodIssueCode.custom,
251
+ path: ['amountFact'],
252
+ message: 'amount bands require an explicit amount fact',
253
+ });
254
+ }
255
+ let previousAmount = BigInt(0);
256
+ requirement.stages.forEach((stage, index) => {
257
+ if (index === 0) {
258
+ if (stage.minimumAmount !== undefined) {
259
+ context.addIssue({
260
+ code: z.ZodIssueCode.custom,
261
+ path: ['stages', index, 'minimumAmount'],
262
+ message: 'the first stage must apply to every amount',
263
+ });
264
+ }
265
+ return;
266
+ }
267
+ if (!hasBands)
268
+ return;
269
+ if (stage.minimumAmount === undefined ||
270
+ !/^(0|[1-9][0-9]*)$/.test(stage.minimumAmount) ||
271
+ BigInt(stage.minimumAmount) <= previousAmount) {
272
+ context.addIssue({
273
+ code: z.ZodIssueCode.custom,
274
+ path: ['stages', index, 'minimumAmount'],
275
+ message: 'stage amount thresholds must be positive and strictly increasing',
276
+ });
277
+ }
278
+ else {
279
+ previousAmount = BigInt(stage.minimumAmount);
280
+ }
281
+ });
282
+ requirement.safeKnobs?.forEach((knob, index) => {
283
+ const stage = stagesById.get(knob.stageId);
284
+ if (stage === undefined) {
285
+ context.addIssue({
286
+ code: z.ZodIssueCode.custom,
287
+ path: ['safeKnobs', index, 'stageId'],
288
+ message: 'safe knob must reference an existing stage',
289
+ });
290
+ return;
291
+ }
292
+ const settingKey = `${knob.stageId}:${knob.kind === 'minimum_amount' ? 'amount' : 'participation'}`;
293
+ if (configuredStageIds.has(settingKey)) {
294
+ context.addIssue({
295
+ code: z.ZodIssueCode.custom,
296
+ path: ['safeKnobs', index, 'stageId'],
297
+ message: 'a stage may expose one participation setting and one amount threshold',
298
+ });
299
+ }
300
+ configuredStageIds.add(settingKey);
301
+ if (knob.kind === 'minimum_amount') {
302
+ if (stage.minimumAmount === undefined) {
303
+ context.addIssue({
304
+ code: z.ZodIssueCode.custom,
305
+ path: ['safeKnobs', index, 'stageId'],
306
+ message: 'amount settings must reference a declared stage threshold',
307
+ });
308
+ }
309
+ return;
310
+ }
311
+ if (knob.kind === 'required_approvals') {
312
+ if (typeof stage.requiredApprovals !== 'number') {
313
+ context.addIssue({
314
+ code: z.ZodIssueCode.custom,
315
+ path: ['safeKnobs', index, 'stageId'],
316
+ message: 'required count ranges apply only to numeric approval counts',
317
+ });
318
+ }
319
+ else if (stage.requiredApprovals < knob.min || stage.requiredApprovals > knob.max) {
320
+ context.addIssue({
321
+ code: z.ZodIssueCode.custom,
322
+ path: ['safeKnobs', index],
323
+ message: 'the published approval count must be within the configurable range',
324
+ });
325
+ }
326
+ return;
327
+ }
328
+ const defaultOption = knob.options.find((option) => option.id === knob.defaultOptionId);
329
+ if (defaultOption === undefined) {
330
+ context.addIssue({
331
+ code: z.ZodIssueCode.custom,
332
+ path: ['safeKnobs', index, 'defaultOptionId'],
333
+ message: 'default group must reference a declared option',
334
+ });
335
+ }
336
+ else if (JSON.stringify(defaultOption.eligibility) !== JSON.stringify(stage.eligibility)) {
337
+ context.addIssue({
338
+ code: z.ZodIssueCode.custom,
339
+ path: ['safeKnobs', index, 'defaultOptionId'],
340
+ message: 'default group must match the published stage eligibility',
341
+ });
342
+ }
343
+ });
344
+ });
345
+ export const permissionsV2ConditionalApprovalCaseStatusSchema = z.enum([
346
+ 'pending',
347
+ 'completed',
348
+ 'rejected',
349
+ 'expired',
350
+ 'invalidated',
351
+ ]);
352
+ export const permissionsV2ConditionalApprovalDecisionUnavailableReasonSchema = z.enum([
353
+ 'not_eligible',
354
+ 'initiator',
355
+ 'already_decided',
356
+ 'case_terminal',
357
+ 'authority_changed',
358
+ ]);
359
+ export const permissionsV2ConditionalApprovalDecisionCapabilitySchema = z.discriminatedUnion('canDecide', [
360
+ z
361
+ .object({
362
+ canDecide: z.literal(true),
363
+ intents: z.tuple([z.literal('approve'), z.literal('reject')]),
364
+ })
365
+ .strict(),
366
+ z
367
+ .object({
368
+ canDecide: z.literal(false),
369
+ reason: permissionsV2ConditionalApprovalDecisionUnavailableReasonSchema,
370
+ })
371
+ .strict(),
372
+ ]);
373
+ export const permissionsV2ConditionalApprovalRequirementIdentitySchema = z
374
+ .object({
375
+ requirementId: conditionalApprovalIdentifierSchema,
376
+ policyId: conditionalApprovalIdentifierSchema,
377
+ policyVersion: conditionalApprovalIdentifierSchema,
378
+ ruleId: conditionalApprovalIdentifierSchema,
379
+ stackHash: z.string().min(1),
380
+ authorizationScopeId: conditionalApprovalActorIdSchema,
381
+ configurationHash: z.string().min(1).optional(),
382
+ })
383
+ .strict();
384
+ const conditionalApprovalCaseStageViewSchema = z
385
+ .object({
386
+ id: conditionalApprovalIdentifierSchema,
387
+ requiredApprovals: z.number().int().min(1).max(25),
388
+ eligibleActorCount: z.number().int().min(1).max(100),
389
+ approvedActorIds: z
390
+ .array(conditionalApprovalActorIdSchema)
391
+ .refine((actorIds) => new Set(actorIds).size === actorIds.length, {
392
+ message: 'approved actor identifiers must be unique',
393
+ }),
394
+ })
395
+ .strict();
396
+ const conditionalApprovalRequestArgsSchema = z
397
+ .record(conditionalApprovalIdentifierSchema, z.string().min(1).max(512))
398
+ .refine((args) => Object.keys(args).length <= 25, {
399
+ message: 'request summaries may include at most twenty-five arguments',
400
+ });
401
+ export const permissionsV2ConditionalApprovalCaseViewSchema = z
402
+ .object({
403
+ kind: z.literal('conditional_approval'),
404
+ caseId: conditionalApprovalIdentifierSchema,
405
+ status: permissionsV2ConditionalApprovalCaseStatusSchema,
406
+ evidence: z.enum(['authenticated_approval', 'transaction_signature']).optional(),
407
+ request: z
408
+ .object({
409
+ id: conditionalApprovalRequestIdSchema,
410
+ requestHash: nonEmptyStringSchema,
411
+ walletId: nonEmptyStringSchema,
412
+ requestType: permissionsV2SigningRequestTypeSchema,
413
+ chainId: nonEmptyStringSchema.optional(),
414
+ classification: nonEmptyStringSchema,
415
+ // Signature collections expose only an encoded source; some native payloads have none.
416
+ from: nonEmptyStringSchema.optional(),
417
+ to: nonEmptyStringSchema.optional(),
418
+ value: z
419
+ .object({
420
+ baseUnits: z.string().regex(/^(0|[1-9][0-9]*)$/),
421
+ asset: nonEmptyStringSchema.optional(),
422
+ decimals: z.number().int().nonnegative().optional(),
423
+ })
424
+ .strict()
425
+ .optional(),
426
+ method: z.string().min(1).max(256).optional(),
427
+ payloadDigest: z.string().min(1).max(256).optional(),
428
+ args: conditionalApprovalRequestArgsSchema.optional(),
429
+ })
430
+ .strict(),
431
+ requirementIdentity: permissionsV2ConditionalApprovalRequirementIdentitySchema,
432
+ currentStageIndex: z.number().int().nonnegative(),
433
+ stages: z.array(conditionalApprovalCaseStageViewSchema).min(1).max(5),
434
+ decisions: z
435
+ .array(z
436
+ .object({
437
+ actorId: conditionalApprovalActorIdSchema,
438
+ stageId: conditionalApprovalIdentifierSchema,
439
+ intent: z.enum(['approve', 'reject']),
440
+ decidedAt: z.string().datetime(),
441
+ })
442
+ .strict())
443
+ .max(126),
444
+ expiresAt: z.string().datetime(),
445
+ terminalReason: z.string().min(1).optional(),
446
+ decision: permissionsV2ConditionalApprovalDecisionCapabilitySchema,
447
+ })
448
+ .strict();
449
+ export const permissionsV2AuthorityAssignmentSchema = z.union([
450
+ z
451
+ .object({
452
+ kind: z.literal('role'),
453
+ name: conditionalApprovalNameSchema,
454
+ })
455
+ .strict(),
456
+ z
457
+ .object({
458
+ kind: z.literal('attribute'),
459
+ name: conditionalApprovalNameSchema,
460
+ value: conditionalApprovalNameSchema,
461
+ })
462
+ .strict(),
463
+ ]);
464
+ const conditionalApprovalRevisionSchema = z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER);
465
+ const conditionalApprovalChangeActorSchema = z
466
+ .object({
467
+ type: z.enum(['partner_secret', 'configuration_manager']),
468
+ id: conditionalApprovalActorIdSchema,
469
+ })
470
+ .strict();
471
+ export const permissionsV2AuthoritySetWriteSchema = z
472
+ .object({
473
+ expectedRevision: conditionalApprovalRevisionSchema,
474
+ assignments: z
475
+ .array(permissionsV2AuthorityAssignmentSchema)
476
+ .max(25)
477
+ .refine((assignments) => new Set(assignments.map((assignment) => JSON.stringify(assignment))).size === assignments.length, {
478
+ message: 'authority assignments must be unique',
479
+ }),
480
+ })
481
+ .strict();
482
+ export const permissionsV2AuthoritySetViewSchema = z
483
+ .object({
484
+ userId: conditionalApprovalActorIdSchema,
485
+ partnerId: nonEmptyStringSchema,
486
+ appId: nonEmptyStringSchema,
487
+ authorizationScopeId: conditionalApprovalActorIdSchema,
488
+ revision: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),
489
+ assignments: z.array(permissionsV2AuthorityAssignmentSchema).max(25),
490
+ changedAt: z.string().datetime(),
491
+ changedBy: conditionalApprovalChangeActorSchema,
492
+ })
493
+ .strict();
494
+ export const permissionsV2AuthorizationScopeBindingWriteSchema = z
495
+ .object({
496
+ expectedRevision: conditionalApprovalRevisionSchema,
497
+ authorizationScopeId: conditionalApprovalActorIdSchema,
498
+ })
499
+ .strict();
500
+ export const permissionsV2AuthorizationScopeBindingViewSchema = z
501
+ .object({
502
+ walletId: nonEmptyStringSchema,
503
+ partnerId: nonEmptyStringSchema,
504
+ appId: nonEmptyStringSchema,
505
+ authorizationScopeId: conditionalApprovalActorIdSchema,
506
+ revision: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),
507
+ changedAt: z.string().datetime(),
508
+ changedBy: conditionalApprovalChangeActorSchema,
509
+ })
510
+ .strict();
511
+ const conditionalApprovalConfigurationValuesSchema = z
512
+ .record(conditionalApprovalIdentifierSchema, z.union([z.string(), z.number().int()]))
513
+ .refine((values) => Object.keys(values).length <= 25, {
514
+ message: 'conditional approval configuration may contain at most 25 values',
515
+ });
516
+ export const permissionsV2AuthorizationConfigurationWriteSchema = z
517
+ .object({
518
+ expectedRevision: conditionalApprovalRevisionSchema,
519
+ values: conditionalApprovalConfigurationValuesSchema,
520
+ })
521
+ .strict();
522
+ export const permissionsV2AuthorizationConfigurationViewSchema = z
523
+ .object({
524
+ partnerId: nonEmptyStringSchema,
525
+ appId: nonEmptyStringSchema,
526
+ authorizationScopeId: conditionalApprovalActorIdSchema,
527
+ policyId: conditionalApprovalIdentifierSchema,
528
+ policyVersion: conditionalApprovalIdentifierSchema,
529
+ requirementId: conditionalApprovalIdentifierSchema,
530
+ revision: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),
531
+ values: conditionalApprovalConfigurationValuesSchema,
532
+ configurationHash: nonEmptyStringSchema,
533
+ changedAt: z.string().datetime(),
534
+ changedBy: conditionalApprovalChangeActorSchema,
535
+ })
536
+ .strict();
537
+ export const permissionsV2ConditionalApprovalDecisionSchema = z
538
+ .object({
539
+ intent: z.enum(['approve', 'reject']),
540
+ })
541
+ .strict();
542
+ export const permissionsV2ConditionalApprovalSignatureSchema = z
543
+ .object({
544
+ walletId: z.string().min(1).max(128),
545
+ signature: z.string().min(1).max(512),
546
+ })
547
+ .strict();
548
+ /** Original transaction payloads for signature collection, not caller-provided policy facts. */
549
+ export const permissionsV2TransactionSignatureCollectionSchema = z
550
+ .object({
551
+ requestId: z.string().min(1).max(128),
552
+ walletId: z.string().uuid(),
553
+ transaction: z.discriminatedUnion('format', [
554
+ z
555
+ .object({
556
+ format: z.literal('safe_eip712'),
557
+ typedDataJson: z.string().min(1).max(131072),
558
+ chainId: z
559
+ .string()
560
+ .regex(/^[1-9][0-9]*$/)
561
+ .max(78),
562
+ })
563
+ .strict(),
564
+ z
565
+ .object({
566
+ format: z.literal('evm_typed_data'),
567
+ typedDataJson: z.string().min(1).max(131072),
568
+ chainId: z
569
+ .string()
570
+ .regex(/^[1-9][0-9]*$/)
571
+ .max(78),
572
+ })
573
+ .strict(),
574
+ z
575
+ .object({
576
+ format: z.literal('evm_transaction'),
577
+ transactionBase64: z.string().min(1).max(131072),
578
+ chainId: z
579
+ .string()
580
+ .regex(/^[1-9][0-9]*$/)
581
+ .max(78),
582
+ })
583
+ .strict(),
584
+ z
585
+ .object({
586
+ format: z.literal('solana_transaction'),
587
+ transactionBase64: z.string().min(1).max(131072),
588
+ })
589
+ .strict(),
590
+ z
591
+ .object({
592
+ format: z.literal('cosmos_transaction'),
593
+ signMode: z.enum(['DIRECT', 'AMINO']),
594
+ signDocBase64: z.string().min(1).max(131072),
595
+ })
596
+ .strict(),
597
+ z
598
+ .object({
599
+ format: z.literal('stellar_xdr'),
600
+ transactionXdr: z.string().min(1).max(131072),
601
+ networkPassphrase: z.string().min(1).max(256),
602
+ })
603
+ .strict(),
604
+ z
605
+ .object({
606
+ format: z.literal('sui_transaction'),
607
+ transactionBase64: z.string().min(1).max(131072),
608
+ })
609
+ .strict(),
610
+ ]),
611
+ })
612
+ .strict();
613
+ export const permissionsV2ConditionalApprovalCaseListSchema = z
614
+ .object({
615
+ cases: z.array(permissionsV2ConditionalApprovalCaseViewSchema),
616
+ })
617
+ .strict();
102
618
  export const permissionsV2PolicyRuleSchema = z
103
619
  .object({
104
620
  id: nonEmptyStringSchema,
105
621
  effect: permissionsV2PolicyEffectSchema,
106
622
  when: permissionsV2ConditionSchema,
623
+ approvalRequirement: permissionsV2ConditionalApprovalRequirementSchema.optional(),
107
624
  })
108
- .strict();
625
+ .strict()
626
+ .superRefine((rule, context) => {
627
+ if (rule.approvalRequirement !== undefined && rule.effect !== 'require_approval') {
628
+ context.addIssue({
629
+ code: z.ZodIssueCode.custom,
630
+ path: ['approvalRequirement'],
631
+ message: 'structured approval requirements are only valid for require_approval rules',
632
+ });
633
+ }
634
+ });
635
+ const permissionsV2PolicyRulesSchema = z
636
+ .array(permissionsV2PolicyRuleSchema)
637
+ .min(1)
638
+ .superRefine((rules, context) => {
639
+ const requirementIds = new Set();
640
+ rules.forEach((rule, index) => {
641
+ const requirementId = rule.approvalRequirement?.id;
642
+ if (requirementId === undefined)
643
+ return;
644
+ if (requirementIds.has(requirementId)) {
645
+ context.addIssue({
646
+ code: z.ZodIssueCode.custom,
647
+ path: [index, 'approvalRequirement', 'id'],
648
+ message: 'approval requirement identifiers must be unique within a policy',
649
+ });
650
+ }
651
+ requirementIds.add(requirementId);
652
+ });
653
+ });
109
654
  const partnerPolicyCandidateFields = {
110
655
  id: nonEmptyStringSchema,
111
656
  schemaVersion: z.literal('permissions.policy.v1'),
112
657
  version: nonEmptyStringSchema,
113
658
  selector: permissionsV2PartnerAuthoredPolicySelectorSchema,
114
- rules: z.array(permissionsV2PolicyRuleSchema).min(1),
659
+ rules: permissionsV2PolicyRulesSchema,
115
660
  metadata: permissionsV2PolicyMetadataSchema.optional(),
116
661
  };
117
662
  export const permissionsV2PartnerPolicyCandidateSchema = z.object(partnerPolicyCandidateFields).strict();
@@ -120,7 +665,7 @@ export const permissionsV2PartnerAuthoredPolicyDefinitionSchema = permissionsV2P
120
665
  });
121
666
  export const permissionsV2DelegationPolicyDefinitionSchema = permissionsV2PartnerAuthoredPolicyDefinitionSchema.extend({
122
667
  layer: z.literal('partner'),
123
- selector: permissionsV2PartnerAuthoredPolicySelectorSchema.extend({
668
+ selector: permissionsV2PartnerAuthoredPolicySelectorObjectSchema.extend({
124
669
  partnerId: nonEmptyStringSchema,
125
670
  appId: nonEmptyStringSchema,
126
671
  }),
@@ -142,6 +687,7 @@ export const permissionsV2DelegationConsentMutationSchema = z
142
687
  walletId: nonEmptyStringSchema,
143
688
  policyVersion: nonEmptyStringSchema,
144
689
  policyHash: nonEmptyStringSchema,
690
+ configurationHash: nonEmptyStringSchema.optional(),
145
691
  expiresAt: z.string().datetime().optional(),
146
692
  })
147
693
  .strict();
@@ -150,6 +696,23 @@ export const permissionsV2DelegationConsentStandingMutationSchema = permissionsV
150
696
  pendingTransactionId: nonEmptyStringSchema,
151
697
  })
152
698
  .strict();
699
+ export const permissionsV2DelegationConsentNativeStandingMutationSchema = permissionsV2DelegationConsentMutationSchema
700
+ .extend({
701
+ requestId: permissionsV2TransactionSignatureCollectionSchema.shape.requestId,
702
+ walletId: permissionsV2TransactionSignatureCollectionSchema.shape.walletId,
703
+ transaction: permissionsV2TransactionSignatureCollectionSchema.shape.transaction,
704
+ })
705
+ .strict();
706
+ export const permissionsV2DelegationConsentStandingRouteMutationSchema = z.union([
707
+ permissionsV2DelegationConsentStandingMutationSchema,
708
+ permissionsV2DelegationConsentNativeStandingMutationSchema,
709
+ ]);
710
+ /** Explicit owner consent, optionally committed together with personal settings. */
711
+ export const permissionsV2DelegationConsentSubmissionSchema = permissionsV2DelegationConsentMutationSchema.extend({
712
+ posture: z.enum(['standing', 'manual_review']),
713
+ pendingTransactionId: nonEmptyStringSchema.optional(),
714
+ settings: permissionsV2UserParameterSaveSchema.pick({ expectedRevision: true, values: true }).optional(),
715
+ });
153
716
  export const permissionsV2DelegationConsentViewSchema = z
154
717
  .object({
155
718
  status: permissionsV2DelegationConsentApiStatusSchema,
@@ -160,6 +723,7 @@ export const permissionsV2DelegationConsentViewSchema = z
160
723
  policyId: nonEmptyStringSchema,
161
724
  policyVersion: nonEmptyStringSchema,
162
725
  policyHash: nonEmptyStringSchema,
726
+ configurationHash: nonEmptyStringSchema.optional(),
163
727
  grantedAt: z.string().datetime().optional(),
164
728
  expiresAt: z.string().datetime().optional(),
165
729
  revokedAt: z.string().datetime().optional(),
@@ -171,6 +735,12 @@ export const permissionsV2DelegationConsentRequestSchema = z
171
735
  consent: permissionsV2DelegationConsentViewSchema,
172
736
  })
173
737
  .strict();
738
+ export const permissionsV2DelegationConsentSubmissionResponseSchema = z
739
+ .object({
740
+ consent: permissionsV2DelegationConsentViewSchema,
741
+ settings: permissionsV2UserParameterViewSchema.nullable(),
742
+ })
743
+ .strict();
174
744
  export const permissionsV2DelegationConsentDiscoveryResponseSchema = z
175
745
  .object({
176
746
  requests: z.array(permissionsV2DelegationConsentRequestSchema),