@crediolabs/policy-synth 0.1.12 → 0.1.13
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/dist/install/build-install-policy.d.ts +218 -0
- package/dist/install/build-install-policy.js +427 -0
- package/dist/install/get-interpreter-info.d.ts +29 -0
- package/dist/install/get-interpreter-info.js +41 -0
- package/dist/run/index.d.ts +49 -4
- package/dist/run/index.js +324 -4
- package/dist/run/schemas.d.ts +1500 -4
- package/dist/run/schemas.js +288 -0
- package/dist-cjs/install/build-install-policy.d.ts +218 -0
- package/dist-cjs/install/build-install-policy.js +431 -0
- package/dist-cjs/install/get-interpreter-info.d.ts +29 -0
- package/dist-cjs/install/get-interpreter-info.js +44 -0
- package/dist-cjs/run/index.d.ts +49 -4
- package/dist-cjs/run/index.js +339 -3
- package/dist-cjs/run/schemas.d.ts +1500 -4
- package/dist-cjs/run/schemas.js +289 -1
- package/package.json +1 -1
- package/src/install/build-install-policy.ts +686 -0
- package/src/install/get-interpreter-info.ts +68 -0
- package/src/run/index.ts +405 -5
- package/src/run/schemas.ts +326 -0
package/dist-cjs/run/schemas.js
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
// imports them here so its tool-shape bindings stay in step; the CLI imports
|
|
17
17
|
// them here so it can build the same args envelope the MCP transport builds.
|
|
18
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
-
exports.ToolErrorSchema = exports.SynthesizePolicyInputSchema = exports.SynthesizePolicyRecordingInputSchema = exports.InterpreterOptionsSchema = exports.SynthesizePolicyMandateInputSchema = exports.RecordTransactionInputSchema = exports.OzAdapterConfigSchema = exports.ComposeUserResponsesSchema = exports.MandateSpecSchema = exports.RecordedTransactionSchema = exports.ParseConfidenceSchema = exports.OnChainEventSchema = exports.TokenMovementSchema = exports.ContractInvocationSchema = exports.ScValSchema = exports.NetworkSchema = void 0;
|
|
19
|
+
exports.ToolErrorSchema = exports.GetInterpreterInfoInputSchema = exports.RevokePolicyInputSchema = exports.InstallPolicyInputSchema = exports.NETWORK_PASSPHRASES = exports.DEFAULT_AUTH_VALID_UNTIL_LEDGERS = exports.TESTNET_RPC_URL = exports.PINNED_INTERPRETER_GRAMMAR_VERSION = exports.PINNED_INTERPRETER_WASM_SHA256 = exports.PINNED_INTERPRETER_TESTNET_ADDRESS = exports.VerifyPolicyInputSchema = exports.SimulatePolicyInputSchema = exports.OraclePriceFixtureSchema = exports.PredicateNodeSchema = exports.PredicateLeafSchema = exports.SynthesizePolicyInputSchema = exports.SynthesizePolicyRecordingInputSchema = exports.InterpreterOptionsSchema = exports.SynthesizePolicyMandateInputSchema = exports.RecordTransactionInputSchema = exports.OzAdapterConfigSchema = exports.ComposeUserResponsesSchema = exports.MandateSpecSchema = exports.RecordedTransactionSchema = exports.ParseConfidenceSchema = exports.OnChainEventSchema = exports.TokenMovementSchema = exports.ContractInvocationSchema = exports.ScValSchema = exports.NetworkSchema = void 0;
|
|
20
20
|
const zod_1 = require("zod");
|
|
21
21
|
const address_ts_1 = require("../synth/address.js");
|
|
22
22
|
/** Soroban `valid_until` is a u32 ledger sequence; a value above this cannot be
|
|
@@ -222,6 +222,294 @@ exports.SynthesizePolicyInputSchema = zod_1.z.discriminatedUnion('source', [
|
|
|
222
222
|
exports.SynthesizePolicyMandateInputSchema,
|
|
223
223
|
exports.SynthesizePolicyRecordingInputSchema,
|
|
224
224
|
]);
|
|
225
|
+
// ===== PredicateNode / PredicateLeaf =====
|
|
226
|
+
//
|
|
227
|
+
// Hand-written zod mirrors of the predicate grammar in types.ts:132-180.
|
|
228
|
+
// Recursive (`and`/`or`/`not` nest), so the schemas use the same
|
|
229
|
+
// `z.lazy` + explicit `z.ZodType<unknown>` annotation that ScValSchema
|
|
230
|
+
// already uses - without the annotation TS's circular type inference
|
|
231
|
+
// breaks the recursive reference. i128-shaped numerics (`num`, `den`)
|
|
232
|
+
// are decimal STRINGS, never JS numbers, matching the on-chain i128
|
|
233
|
+
// convention used everywhere else in this file. The grammar is the
|
|
234
|
+
// single source of truth (types.ts); a drift test in this package
|
|
235
|
+
// asserts the two stay in step.
|
|
236
|
+
/** PredicateLeaf mirrors the core `PredicateLeaf` union. Every variant
|
|
237
|
+
* is a `kind` discriminator; literals carry their primitive value inline.
|
|
238
|
+
* `literal_vec.elements` is recursive (a vec may contain literals that
|
|
239
|
+
* themselves nest) so the leaf schema is lazily self-referential. */
|
|
240
|
+
exports.PredicateLeafSchema = zod_1.z.lazy(() => zod_1.z.union([
|
|
241
|
+
zod_1.z.object({ kind: zod_1.z.literal('call_contract') }),
|
|
242
|
+
zod_1.z.object({ kind: zod_1.z.literal('call_fn') }),
|
|
243
|
+
zod_1.z.object({ kind: zod_1.z.literal('call_arg'), index: zod_1.z.number().int().nonnegative() }),
|
|
244
|
+
zod_1.z.object({ kind: zod_1.z.literal('call_arg_len'), index: zod_1.z.number().int().nonnegative() }),
|
|
245
|
+
zod_1.z.object({
|
|
246
|
+
kind: zod_1.z.literal('call_arg_field'),
|
|
247
|
+
index: zod_1.z.number().int().nonnegative(),
|
|
248
|
+
element: zod_1.z.number().int().nonnegative(),
|
|
249
|
+
field: zod_1.z.string(),
|
|
250
|
+
}),
|
|
251
|
+
// num/den are i128 on chain; JSON numbers lose precision past 2^53,
|
|
252
|
+
// so the wire is a decimal string. The contract refuses `den == 0` and
|
|
253
|
+
// `num <= 0` / `den <= 0` at install (types.ts:162-163 + the install
|
|
254
|
+
// gate); mirroring that bound here closes the gap where simulate /
|
|
255
|
+
// verify green-light a policy the install gate will reject. The
|
|
256
|
+
// positive-only regex is the cheapest unambiguous check.
|
|
257
|
+
zod_1.z.object({
|
|
258
|
+
kind: zod_1.z.literal('call_arg_scaled'),
|
|
259
|
+
index: zod_1.z.number().int().nonnegative(),
|
|
260
|
+
num: zod_1.z.string().regex(/^[1-9][0-9]*$/),
|
|
261
|
+
den: zod_1.z.string().regex(/^[1-9][0-9]*$/),
|
|
262
|
+
}),
|
|
263
|
+
zod_1.z.object({ kind: zod_1.z.literal('amount'), token: zod_1.z.string() }),
|
|
264
|
+
zod_1.z.object({
|
|
265
|
+
kind: zod_1.z.literal('window_spent'),
|
|
266
|
+
token: zod_1.z.string(),
|
|
267
|
+
windowSeconds: zod_1.z.number().int().positive(),
|
|
268
|
+
}),
|
|
269
|
+
zod_1.z.object({ kind: zod_1.z.literal('now') }),
|
|
270
|
+
zod_1.z.object({ kind: zod_1.z.literal('valid_until') }),
|
|
271
|
+
zod_1.z.object({
|
|
272
|
+
kind: zod_1.z.literal('invocation_count_in_window'),
|
|
273
|
+
windowSecs: zod_1.z.number().int().positive(),
|
|
274
|
+
}),
|
|
275
|
+
zod_1.z.object({ kind: zod_1.z.literal('oracle_price'), asset: zod_1.z.string() }),
|
|
276
|
+
zod_1.z.object({
|
|
277
|
+
kind: zod_1.z.literal('oracle_threshold'),
|
|
278
|
+
value: zod_1.z.string().regex(/^-?[0-9]+$/),
|
|
279
|
+
decimals: zod_1.z.number().int().nonnegative(),
|
|
280
|
+
}),
|
|
281
|
+
zod_1.z.object({ kind: zod_1.z.literal('literal_address'), value: zod_1.z.string() }),
|
|
282
|
+
zod_1.z.object({ kind: zod_1.z.literal('literal_i128'), value: zod_1.z.string().regex(/^-?[0-9]+$/) }),
|
|
283
|
+
zod_1.z.object({ kind: zod_1.z.literal('literal_symbol'), value: zod_1.z.string() }),
|
|
284
|
+
// `literal_u32` is u32 on chain. A negative value would wrap, and a
|
|
285
|
+
// value above U32_MAX would be refused at the encode boundary
|
|
286
|
+
// anyway. Bound at the schema so the wire cannot carry a value the
|
|
287
|
+
// contract will reject.
|
|
288
|
+
zod_1.z.object({
|
|
289
|
+
kind: zod_1.z.literal('literal_u32'),
|
|
290
|
+
value: zod_1.z.number().int().nonnegative().max(U32_MAX),
|
|
291
|
+
}),
|
|
292
|
+
zod_1.z.object({ kind: zod_1.z.literal('literal_u64'), value: zod_1.z.string().regex(/^[0-9]+$/) }),
|
|
293
|
+
// `literal_bytes` is hex on chain. `Buffer.from(value, 'hex')` silently
|
|
294
|
+
// drops non-hex chars AND yields an empty buffer when the whole input
|
|
295
|
+
// is non-hex - so a user passing 'zzzz' would get a predicate that
|
|
296
|
+
// compares against empty bytes instead of being rejected. The
|
|
297
|
+
// strict even-length hex regex closes that gap at the boundary.
|
|
298
|
+
zod_1.z.object({
|
|
299
|
+
kind: zod_1.z.literal('literal_bytes'),
|
|
300
|
+
value: zod_1.z
|
|
301
|
+
.string()
|
|
302
|
+
.regex(/^[0-9a-fA-F]*$/)
|
|
303
|
+
.refine((v) => v.length % 2 === 0, 'must be even-length hex'),
|
|
304
|
+
}),
|
|
305
|
+
// elements are themselves PredicateLeaf; lazy to break the cycle.
|
|
306
|
+
zod_1.z.object({ kind: zod_1.z.literal('literal_vec'), elements: zod_1.z.array(exports.PredicateLeafSchema) }),
|
|
307
|
+
]));
|
|
308
|
+
/** PredicateNode mirrors the core `PredicateNode` union. Recursive through
|
|
309
|
+
* `and`/`or`/`not`; the lazy + annotation pattern keeps the recursion
|
|
310
|
+
* type-safe. */
|
|
311
|
+
exports.PredicateNodeSchema = zod_1.z.lazy(() => zod_1.z.union([
|
|
312
|
+
zod_1.z.object({ op: zod_1.z.literal('and'), children: zod_1.z.array(exports.PredicateNodeSchema) }),
|
|
313
|
+
zod_1.z.object({ op: zod_1.z.literal('or'), children: zod_1.z.array(exports.PredicateNodeSchema) }),
|
|
314
|
+
zod_1.z.object({ op: zod_1.z.literal('not'), child: exports.PredicateNodeSchema }),
|
|
315
|
+
zod_1.z.object({
|
|
316
|
+
op: zod_1.z.literal('eq'),
|
|
317
|
+
left: exports.PredicateLeafSchema,
|
|
318
|
+
right: exports.PredicateLeafSchema,
|
|
319
|
+
}),
|
|
320
|
+
zod_1.z.object({
|
|
321
|
+
op: zod_1.z.enum(['lt', 'lte', 'gt', 'gte']),
|
|
322
|
+
left: exports.PredicateLeafSchema,
|
|
323
|
+
right: exports.PredicateLeafSchema,
|
|
324
|
+
}),
|
|
325
|
+
zod_1.z.object({
|
|
326
|
+
op: zod_1.z.literal('in'),
|
|
327
|
+
needle: exports.PredicateLeafSchema,
|
|
328
|
+
haystack: zod_1.z.array(exports.PredicateLeafSchema),
|
|
329
|
+
}),
|
|
330
|
+
]));
|
|
331
|
+
// ===== simulate_policy / verify_policy =====
|
|
332
|
+
//
|
|
333
|
+
// The oracle fixture shape mirrors `SimulateOptions` / `VerifyOptions`
|
|
334
|
+
// in packages/policy-synth/src/verify/{simulate,verify}.ts - the same
|
|
335
|
+
// sorted set of error enum values is used by both engines. u32
|
|
336
|
+
// `validUntilLedger` is bounded at the boundary so a hand-crafted
|
|
337
|
+
// payload cannot leak a u32 overflow into the engine's permit context.
|
|
338
|
+
/** Oracle price fixture - mirror of the entry type in `SimulateOptions` /
|
|
339
|
+
* `VerifyOptions`. Discriminated by presence of `error` vs `price`. */
|
|
340
|
+
exports.OraclePriceFixtureSchema = zod_1.z.union([
|
|
341
|
+
zod_1.z.object({
|
|
342
|
+
price: zod_1.z.string().regex(/^[0-9]+$/),
|
|
343
|
+
timestampSeconds: zod_1.z.number().int().nonnegative(),
|
|
344
|
+
}),
|
|
345
|
+
zod_1.z.object({
|
|
346
|
+
error: zod_1.z.enum(['stale', 'missing', 'deviation', 'paused', 'decimals', 'fingerprint']),
|
|
347
|
+
}),
|
|
348
|
+
]);
|
|
349
|
+
exports.SimulatePolicyInputSchema = zod_1.z.object({
|
|
350
|
+
// simulatePolicy accepts a null predicate (OZ-only policy); verifyPolicy
|
|
351
|
+
// does not. The asymmetry is mirrored at the schema boundary.
|
|
352
|
+
predicate: exports.PredicateNodeSchema.nullable(),
|
|
353
|
+
permitTx: exports.RecordedTransactionSchema,
|
|
354
|
+
validUntilLedger: zod_1.z.number().int().positive().max(U32_MAX).optional(),
|
|
355
|
+
oraclePricesByAsset: zod_1.z.record(zod_1.z.string(), exports.OraclePriceFixtureSchema).optional(),
|
|
356
|
+
});
|
|
357
|
+
exports.VerifyPolicyInputSchema = zod_1.z.object({
|
|
358
|
+
// verifyPolicy requires a non-null predicate; the engine refuses
|
|
359
|
+
// `null` outright. The schema mirrors that contract.
|
|
360
|
+
predicate: exports.PredicateNodeSchema,
|
|
361
|
+
permitTx: exports.RecordedTransactionSchema,
|
|
362
|
+
validUntilLedger: zod_1.z.number().int().positive().max(U32_MAX).optional(),
|
|
363
|
+
oraclePricesByAsset: zod_1.z.record(zod_1.z.string(), exports.OraclePriceFixtureSchema).optional(),
|
|
364
|
+
});
|
|
365
|
+
// ===== install_policy / revoke_policy / get_interpreter_info =====
|
|
366
|
+
//
|
|
367
|
+
// The install/revoke pair drives the OZ smart-account admin flow. Both surface
|
|
368
|
+
// unsigned Soroban transaction XDRs (base64) and the tool body NEVER signs:
|
|
369
|
+
// the wallet signature IS the user-confirmation step. See `run/index.ts` for
|
|
370
|
+
// the rationale (no `action_id` two-call pair; the MCP server is stateless).
|
|
371
|
+
//
|
|
372
|
+
// `get_interpreter_info` is a read-only fingerprint lookup. It returns the
|
|
373
|
+
// pinned address + grammar version + wasm hash AND, when requested, runs an
|
|
374
|
+
// optional `grammar_version()` RPC call to check whether the deployed contract
|
|
375
|
+
// matches the pin. A mismatch is worth MORE than a fabricated audit field.
|
|
376
|
+
//
|
|
377
|
+
// All three input schemas live BELOW the MandateSpecSchemaForRule declaration
|
|
378
|
+
// so the const reference there is not in the temporal dead zone (no JS hoisting
|
|
379
|
+
// for `const`).
|
|
380
|
+
/** Minimal rule-draft schema for the install input. Mirrors ContextRuleDraft
|
|
381
|
+
* from the core (`types.ts`); we keep this hand-rolled + flat rather than
|
|
382
|
+
* importing the recursive discriminated union because the wire shape is
|
|
383
|
+
* fixed (the user supplies one rule, not a nested AST). Declared BEFORE
|
|
384
|
+
* InstallPolicyInputSchema below so the const reference there is not in
|
|
385
|
+
* the temporal dead zone (no JS hoisting for `const`). */
|
|
386
|
+
const MAX_SIGNERS_PER_RULE = 15;
|
|
387
|
+
const MAX_POLICIES_PER_RULE = 5;
|
|
388
|
+
const MandateSpecSchemaForRule = zod_1.z
|
|
389
|
+
.object({
|
|
390
|
+
contextRuleType: zod_1.z.discriminatedUnion('kind', [
|
|
391
|
+
zod_1.z.object({ kind: zod_1.z.literal('default') }),
|
|
392
|
+
zod_1.z.object({ kind: zod_1.z.literal('call_contract'), contract: zod_1.z.string() }),
|
|
393
|
+
zod_1.z.object({ kind: zod_1.z.literal('create_contract'), wasmHash: zod_1.z.string() }),
|
|
394
|
+
]),
|
|
395
|
+
name: zod_1.z.string().min(1),
|
|
396
|
+
validUntilLedger: zod_1.z.number().int().positive().max(U32_MAX).nullable(),
|
|
397
|
+
signers: zod_1.z
|
|
398
|
+
.array(zod_1.z.discriminatedUnion('kind', [
|
|
399
|
+
zod_1.z.object({ kind: zod_1.z.literal('delegated'), address: zod_1.z.string() }),
|
|
400
|
+
zod_1.z.object({
|
|
401
|
+
kind: zod_1.z.literal('external'),
|
|
402
|
+
verifier: zod_1.z.string(),
|
|
403
|
+
keyBytes: zod_1.z.string(),
|
|
404
|
+
}),
|
|
405
|
+
]))
|
|
406
|
+
.max(MAX_SIGNERS_PER_RULE),
|
|
407
|
+
policies: zod_1.z
|
|
408
|
+
.array(zod_1.z.discriminatedUnion('kind', [
|
|
409
|
+
zod_1.z.object({
|
|
410
|
+
kind: zod_1.z.literal('interpreter'),
|
|
411
|
+
interpreterAddress: zod_1.z.string(),
|
|
412
|
+
predicateBlobBase64: zod_1.z.string().min(1),
|
|
413
|
+
}),
|
|
414
|
+
zod_1.z.object({
|
|
415
|
+
kind: zod_1.z.literal('oz_builtin'),
|
|
416
|
+
primitive: zod_1.z.object({
|
|
417
|
+
primitive: zod_1.z.enum(['spending_limit', 'simple_threshold', 'weighted_threshold']),
|
|
418
|
+
params: zod_1.z.record(zod_1.z.unknown()),
|
|
419
|
+
}),
|
|
420
|
+
instanceAddress: zod_1.z.string(),
|
|
421
|
+
}),
|
|
422
|
+
]))
|
|
423
|
+
.max(MAX_POLICIES_PER_RULE),
|
|
424
|
+
})
|
|
425
|
+
.passthrough()
|
|
426
|
+
.refine((v) => !(v.signers.length === 0 && v.policies.length === 0), 'a rule with no signers and no policies is refused at install (NoSignersAndPolicies)');
|
|
427
|
+
// install/revoke/get_info schemas live HERE (after the helper) so the const
|
|
428
|
+
// reference resolves at module init. They are the new tools on top of the
|
|
429
|
+
// existing four.
|
|
430
|
+
/** Pinned interpreter address (testnet). Mirrors DEPLOYMENTS.md:156-157.
|
|
431
|
+
* Single source for the MCP layer; do not embed elsewhere. */
|
|
432
|
+
exports.PINNED_INTERPRETER_TESTNET_ADDRESS = 'CDR4NLV22STCXFGZPNKDQTEANWLF7LZ6AJLY6B7CLJXKHDZGYJWIOKGP';
|
|
433
|
+
/** Pinned interpreter wasm sha256 (hex). Mirrors DEPLOYMENTS.md:156-157. */
|
|
434
|
+
exports.PINNED_INTERPRETER_WASM_SHA256 = '6e6c13d93e197aa380303a42cd120f5ddb080dd36ef2a343ee1dbd04ca52a443';
|
|
435
|
+
/** The grammar version the interpreter enforces (matches SELF_VERSION in
|
|
436
|
+
* packages/policy-interpreter/src/version.rs). */
|
|
437
|
+
exports.PINNED_INTERPRETER_GRAMMAR_VERSION = 1;
|
|
438
|
+
/** Default Soroban RPC for the install / revoke / info tools. The recorder
|
|
439
|
+
* keeps its own copy in record/rpc.ts because it hands back a fetcher rather
|
|
440
|
+
* than a Server; the two are deliberately different surfaces, so this is
|
|
441
|
+
* pinned beside the addresses it is used with rather than shared. */
|
|
442
|
+
exports.TESTNET_RPC_URL = 'https://soroban-testnet.stellar.org';
|
|
443
|
+
/** Soroban `valid_until` window (ledgers) added to the latest ledger when
|
|
444
|
+
* building the auth entry. ~25 minutes at 5s/ledger. */
|
|
445
|
+
exports.DEFAULT_AUTH_VALID_UNTIL_LEDGERS = 300;
|
|
446
|
+
/** Stellar network passphrases. Pinned here so the XDR envelope uses the
|
|
447
|
+
* matching passphrase when the wallet signs (a mismatch yields invalid
|
|
448
|
+
* hashes). */
|
|
449
|
+
exports.NETWORK_PASSPHRASES = {
|
|
450
|
+
testnet: 'Test SDF Network ; September 2015',
|
|
451
|
+
mainnet: 'Public Global Stellar Network ; September 2015',
|
|
452
|
+
};
|
|
453
|
+
exports.InstallPolicyInputSchema = zod_1.z
|
|
454
|
+
.object({
|
|
455
|
+
/** The smart account contract address (C...) that will receive the rule. */
|
|
456
|
+
smartAccount: zod_1.z.string(),
|
|
457
|
+
/** The signer that authorises the install (G... wallet). Used only for
|
|
458
|
+
* sequence number + auth nonce simulation; never persisted, never signed. */
|
|
459
|
+
sourceAccount: zod_1.z.string(),
|
|
460
|
+
/** The proposed rule draft. Mirrors the core `ContextRuleDraft` shape. */
|
|
461
|
+
rule: MandateSpecSchemaForRule,
|
|
462
|
+
/** Per-rule install nonce; 1 for a fresh install. */
|
|
463
|
+
installNonce: zod_1.z.number().int().positive(),
|
|
464
|
+
/** Optional RPC URL override. Defaults to the public testnet endpoint
|
|
465
|
+
* (`TESTNET_RPC_URL`); the override is refused unless
|
|
466
|
+
* `allowUnpinnedRpcUrl: true`, because the auth nonce and
|
|
467
|
+
* rootInvocation in the response come from whichever RPC answered. */
|
|
468
|
+
rpcUrl: zod_1.z.string().url().optional(),
|
|
469
|
+
/** Opt-in to using a non-pinned RPC URL. Without this flag the tool
|
|
470
|
+
* refuses any `rpcUrl` other than `TESTNET_RPC_URL` because the
|
|
471
|
+
* caller's auth-digest binds to whatever the RPC returned. */
|
|
472
|
+
allowUnpinnedRpcUrl: zod_1.z.boolean().optional(),
|
|
473
|
+
/** Opt-in to pointing the rule's interpreter policy at any address
|
|
474
|
+
* other than the pinned testnet interpreter. Default-deny: a caller
|
|
475
|
+
* that controls the interpreter can permit everything. */
|
|
476
|
+
allowUnpinnedInterpreter: zod_1.z.boolean().optional(),
|
|
477
|
+
/** Base fee in stroops; defaults to BASE_FEE (100). */
|
|
478
|
+
baseFee: zod_1.z.number().int().positive().optional(),
|
|
479
|
+
})
|
|
480
|
+
.refine((v) => Boolean(v.smartAccount) && Boolean(v.sourceAccount), {
|
|
481
|
+
message: 'smartAccount and sourceAccount are required',
|
|
482
|
+
});
|
|
483
|
+
exports.RevokePolicyInputSchema = zod_1.z
|
|
484
|
+
.object({
|
|
485
|
+
/** The smart account contract address (C...). */
|
|
486
|
+
smartAccount: zod_1.z.string(),
|
|
487
|
+
/** The wallet that will sign the removal. The ACCOUNT decides whether it
|
|
488
|
+
* accepts that signer; this schema does not assert a rule it cannot
|
|
489
|
+
* verify, since the account's source is not in this repo. Proven on
|
|
490
|
+
* testnet: the account's deployer can revoke. */
|
|
491
|
+
sourceAccount: zod_1.z.string(),
|
|
492
|
+
/** The rule id to remove from the smart account + interpreter. */
|
|
493
|
+
ruleId: zod_1.z.number().int().nonnegative(),
|
|
494
|
+
/** Optional RPC URL override; same pin as install. */
|
|
495
|
+
rpcUrl: zod_1.z.string().url().optional(),
|
|
496
|
+
/** Opt-in to using a non-pinned RPC URL. Same semantics as install. */
|
|
497
|
+
allowUnpinnedRpcUrl: zod_1.z.boolean().optional(),
|
|
498
|
+
/** Base fee in stroops; defaults to BASE_FEE (100). */
|
|
499
|
+
baseFee: zod_1.z.number().int().positive().optional(),
|
|
500
|
+
})
|
|
501
|
+
.refine((v) => Boolean(v.smartAccount) && Boolean(v.sourceAccount), {
|
|
502
|
+
message: 'smartAccount and sourceAccount are required',
|
|
503
|
+
});
|
|
504
|
+
exports.GetInterpreterInfoInputSchema = zod_1.z.object({
|
|
505
|
+
/** Network to query. The pin differs per network; defaults to testnet. */
|
|
506
|
+
network: exports.NetworkSchema.optional(),
|
|
507
|
+
/** When true, perform an optional live `grammar_version()` RPC call to
|
|
508
|
+
* verify the deployed contract matches the pin. */
|
|
509
|
+
verifyLive: zod_1.z.boolean().optional(),
|
|
510
|
+
/** Optional RPC URL override. */
|
|
511
|
+
rpcUrl: zod_1.z.string().url().optional(),
|
|
512
|
+
});
|
|
225
513
|
// ===== Error envelope (canonical) =====
|
|
226
514
|
//
|
|
227
515
|
// Mirrors ToolError from packages/policy-synth/src/errors.ts. We use a
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crediolabs/policy-synth",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.13",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Off-chain TypeScript synthesis core for the OZ Accounts Policy Builder. Records Soroban transactions, synthesises the minimal policy that permits exactly that flow, verifies it, and returns an unsigned install transaction.",
|
|
6
6
|
"type": "module",
|