@crediolabs/policy-synth 0.2.0 → 0.3.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.
Files changed (184) hide show
  1. package/README.md +4 -4
  2. package/dist/adapters/interpreter/adapter.d.ts +19 -25
  3. package/dist/adapters/interpreter/adapter.js +54 -487
  4. package/dist/adapters/interpreter/index.d.ts +1 -1
  5. package/dist/adapters/interpreter/index.js +1 -1
  6. package/dist/adapters/oz/adapter.js +1 -15
  7. package/dist/errors.d.ts +1 -1
  8. package/dist/index.d.ts +1 -4
  9. package/dist/index.js +1 -4
  10. package/dist/install/build-add-context-rule.d.ts +3 -19
  11. package/dist/install/build-add-context-rule.js +3 -98
  12. package/dist/install/build-install-policy.d.ts +4 -53
  13. package/dist/install/build-install-policy.js +44 -123
  14. package/dist/install/index.d.ts +0 -2
  15. package/dist/install/index.js +0 -7
  16. package/dist/ir/index.d.ts +1 -1
  17. package/dist/ir/types.d.ts +7 -76
  18. package/dist/ir/types.js +0 -2
  19. package/dist/predicate/decode.d.ts +1 -1
  20. package/dist/predicate/decode.js +2 -70
  21. package/dist/predicate/encode.js +45 -229
  22. package/dist/predicate/from-json.js +1 -42
  23. package/dist/record/decode.js +3 -8
  24. package/dist/review-card/builder.d.ts +4 -3
  25. package/dist/review-card/builder.js +18 -162
  26. package/dist/review-card/cross-check.js +2 -105
  27. package/dist/review-card/render-leaf.d.ts +4 -0
  28. package/dist/review-card/render-leaf.js +47 -0
  29. package/dist/run/index.d.ts +36 -139
  30. package/dist/run/index.js +125 -437
  31. package/dist/run/schemas.d.ts +168 -1929
  32. package/dist/run/schemas.js +40 -269
  33. package/dist/seams/types.d.ts +0 -2
  34. package/dist/simulate/deny-cases.d.ts +26 -0
  35. package/dist/simulate/deny-cases.js +282 -0
  36. package/dist/simulate/evaluate.d.ts +18 -0
  37. package/dist/simulate/evaluate.js +271 -0
  38. package/dist/simulate/index.d.ts +4 -0
  39. package/dist/simulate/index.js +8 -0
  40. package/dist/synth/compose-from-recording.d.ts +24 -51
  41. package/dist/synth/compose-from-recording.js +120 -282
  42. package/dist/synth/deny-cases.d.ts +5 -7
  43. package/dist/synth/deny-cases.js +23 -373
  44. package/dist/synth/evaluate.d.ts +0 -21
  45. package/dist/synth/evaluate.js +56 -336
  46. package/dist/synth/index.d.ts +0 -5
  47. package/dist/synth/index.js +0 -5
  48. package/dist/synth/permit-context.d.ts +2 -9
  49. package/dist/synth/permit-context.js +1 -82
  50. package/dist/synth/synthesize-from-recording.d.ts +1 -29
  51. package/dist/synth/synthesize-from-recording.js +41 -356
  52. package/dist/types.d.ts +8 -60
  53. package/dist/types.js +5 -2
  54. package/dist/verify/simulate.d.ts +1 -14
  55. package/dist/verify/simulate.js +2 -88
  56. package/dist/verify/verify.d.ts +1 -7
  57. package/dist/verify/verify.js +0 -8
  58. package/dist-cjs/adapters/interpreter/adapter.d.ts +19 -25
  59. package/dist-cjs/adapters/interpreter/adapter.js +56 -489
  60. package/dist-cjs/adapters/interpreter/index.d.ts +1 -1
  61. package/dist-cjs/adapters/interpreter/index.js +1 -2
  62. package/dist-cjs/adapters/oz/adapter.js +1 -15
  63. package/dist-cjs/errors.d.ts +1 -1
  64. package/dist-cjs/index.d.ts +1 -4
  65. package/dist-cjs/index.js +1 -4
  66. package/dist-cjs/install/build-add-context-rule.d.ts +3 -19
  67. package/dist-cjs/install/build-add-context-rule.js +1 -97
  68. package/dist-cjs/install/build-install-policy.d.ts +4 -53
  69. package/dist-cjs/install/build-install-policy.js +44 -122
  70. package/dist-cjs/install/index.d.ts +0 -2
  71. package/dist-cjs/install/index.js +2 -23
  72. package/dist-cjs/ir/index.d.ts +1 -1
  73. package/dist-cjs/ir/types.d.ts +7 -76
  74. package/dist-cjs/ir/types.js +0 -2
  75. package/dist-cjs/predicate/decode.d.ts +1 -1
  76. package/dist-cjs/predicate/decode.js +2 -70
  77. package/dist-cjs/predicate/encode.js +45 -229
  78. package/dist-cjs/predicate/from-json.js +1 -42
  79. package/dist-cjs/record/decode.js +3 -8
  80. package/dist-cjs/review-card/builder.d.ts +4 -3
  81. package/dist-cjs/review-card/builder.js +23 -167
  82. package/dist-cjs/review-card/cross-check.js +7 -110
  83. package/dist-cjs/review-card/render-leaf.d.ts +4 -0
  84. package/dist-cjs/review-card/render-leaf.js +52 -0
  85. package/dist-cjs/run/index.d.ts +36 -139
  86. package/dist-cjs/run/index.js +125 -444
  87. package/dist-cjs/run/schemas.d.ts +168 -1929
  88. package/dist-cjs/run/schemas.js +41 -270
  89. package/dist-cjs/seams/types.d.ts +0 -2
  90. package/dist-cjs/simulate/deny-cases.d.ts +26 -0
  91. package/dist-cjs/simulate/deny-cases.js +286 -0
  92. package/dist-cjs/simulate/evaluate.d.ts +18 -0
  93. package/dist-cjs/simulate/evaluate.js +274 -0
  94. package/dist-cjs/simulate/index.d.ts +4 -0
  95. package/dist-cjs/simulate/index.js +13 -0
  96. package/dist-cjs/synth/compose-from-recording.d.ts +24 -51
  97. package/dist-cjs/synth/compose-from-recording.js +120 -282
  98. package/dist-cjs/synth/deny-cases.d.ts +5 -7
  99. package/dist-cjs/synth/deny-cases.js +23 -374
  100. package/dist-cjs/synth/evaluate.d.ts +0 -21
  101. package/dist-cjs/synth/evaluate.js +57 -337
  102. package/dist-cjs/synth/index.d.ts +0 -5
  103. package/dist-cjs/synth/index.js +1 -11
  104. package/dist-cjs/synth/permit-context.d.ts +2 -9
  105. package/dist-cjs/synth/permit-context.js +1 -82
  106. package/dist-cjs/synth/synthesize-from-recording.d.ts +1 -29
  107. package/dist-cjs/synth/synthesize-from-recording.js +39 -354
  108. package/dist-cjs/types.d.ts +8 -60
  109. package/dist-cjs/types.js +6 -3
  110. package/dist-cjs/verify/simulate.d.ts +1 -14
  111. package/dist-cjs/verify/simulate.js +2 -88
  112. package/dist-cjs/verify/verify.d.ts +1 -7
  113. package/dist-cjs/verify/verify.js +0 -8
  114. package/package.json +4 -4
  115. package/src/adapters/interpreter/adapter.ts +76 -572
  116. package/src/errors.ts +0 -19
  117. package/src/index.ts +1 -4
  118. package/src/install/build-add-context-rule.ts +5 -139
  119. package/src/install/build-install-policy.ts +93 -214
  120. package/src/install/index.ts +0 -34
  121. package/src/predicate/decode.ts +2 -70
  122. package/src/predicate/encode.ts +49 -261
  123. package/src/predicate/from-json.ts +1 -43
  124. package/src/record/decode.ts +3 -8
  125. package/src/review-card/builder.ts +19 -168
  126. package/src/review-card/cross-check.ts +3 -105
  127. package/src/review-card/render-leaf.ts +48 -0
  128. package/src/run/index.ts +144 -572
  129. package/src/run/schemas.ts +42 -291
  130. package/src/simulate/deny-cases.ts +334 -0
  131. package/src/simulate/evaluate.ts +284 -0
  132. package/src/simulate/index.ts +11 -0
  133. package/src/synth/compose-from-recording.ts +148 -347
  134. package/src/synth/index.ts +0 -13
  135. package/src/synth/synthesize-from-recording.ts +43 -456
  136. package/src/types.ts +13 -49
  137. package/dist/install/authority-overlap.d.ts +0 -134
  138. package/dist/install/authority-overlap.js +0 -0
  139. package/dist/install/build-install-predicate.d.ts +0 -96
  140. package/dist/install/build-install-predicate.js +0 -444
  141. package/dist/install/build-merge-policy.d.ts +0 -70
  142. package/dist/install/build-merge-policy.js +0 -130
  143. package/dist/install/plan-merge-policy.d.ts +0 -49
  144. package/dist/install/plan-merge-policy.js +0 -86
  145. package/dist/install/read-account-rules.d.ts +0 -100
  146. package/dist/install/read-account-rules.js +0 -283
  147. package/dist-cjs/install/authority-overlap.d.ts +0 -134
  148. package/dist-cjs/install/authority-overlap.js +0 -0
  149. package/dist-cjs/install/build-install-predicate.d.ts +0 -96
  150. package/dist-cjs/install/build-install-predicate.js +0 -479
  151. package/dist-cjs/install/build-merge-policy.d.ts +0 -70
  152. package/dist-cjs/install/build-merge-policy.js +0 -134
  153. package/dist-cjs/install/plan-merge-policy.d.ts +0 -49
  154. package/dist-cjs/install/plan-merge-policy.js +0 -90
  155. package/dist-cjs/install/read-account-rules.d.ts +0 -100
  156. package/dist-cjs/install/read-account-rules.js +0 -296
  157. package/src/adapters/interpreter/index.ts +0 -8
  158. package/src/adapters/oz/adapter.ts +0 -376
  159. package/src/adapters/oz/index.ts +0 -9
  160. package/src/codegen/compile-gate.ts +0 -167
  161. package/src/codegen/index.ts +0 -17
  162. package/src/codegen/template.ts +0 -165
  163. package/src/install/authority-overlap.ts +0 -0
  164. package/src/install/build-merge-policy.ts +0 -219
  165. package/src/install/plan-merge-policy.ts +0 -133
  166. package/src/install/read-account-rules.ts +0 -376
  167. package/src/ir/index.ts +0 -13
  168. package/src/ir/types.ts +0 -132
  169. package/src/mandate/index.ts +0 -4
  170. package/src/mandate/to-ir.ts +0 -71
  171. package/src/mandate/types.ts +0 -21
  172. package/src/seams/index.ts +0 -11
  173. package/src/seams/types.ts +0 -81
  174. package/src/synth/deny-cases.ts +0 -663
  175. package/src/synth/evaluate.ts +0 -613
  176. package/src/synth/harness.ts +0 -68
  177. package/src/synth/minimize.ts +0 -48
  178. package/src/synth/permit-context.ts +0 -136
  179. package/src/synth/predicate-literals.ts +0 -27
  180. package/src/synth/synthesize-from-mandate.ts +0 -82
  181. package/src/verify/envelope.ts +0 -28
  182. package/src/verify/index.ts +0 -5
  183. package/src/verify/simulate.ts +0 -311
  184. package/src/verify/verify.ts +0 -243
@@ -7,7 +7,7 @@
7
7
  // expiry.validUntilLedger -> ContextRuleDraft.validUntilLedger
8
8
  // window_spent(t,w) <= L -> `spending_limit` primitive
9
9
  // approval.threshold -> `simple_threshold` / `weighted_threshold`
10
- // Anything needing a capability this backend lacks (oracle price, invocation
10
+ // Anything needing a capability this backend lacks (invocation
11
11
  // count, per-arg comparison/allowlist, guard, nested boolean predicate) is NOT
12
12
  // emitted: it is named in `uncovered` and `covered` is set false. Nothing is
13
13
  // silently dropped.
@@ -45,8 +45,6 @@ const CAPABILITIES = {
45
45
  supportsSpendWindow: true,
46
46
  supportsThreshold: true,
47
47
  supportsTimeExpiry: true,
48
- supportsOraclePrice: false,
49
- supportsInvocationCount: false,
50
48
  supportsGeneralPredicate: false,
51
49
  };
52
50
  function createOzAdapter(config) {
@@ -211,10 +209,6 @@ function matchSpendingLimit(c) {
211
209
  * cannot express, used to populate `uncovered`. */
212
210
  function describeCondition(cond) {
213
211
  switch (cond.op) {
214
- case 'slippage_floor':
215
- // OZ primitives bound a value against a constant; this bounds one call
216
- // argument against another, which none of them can express.
217
- return `slippage floor on arg[${cond.outArgIndex}] (OZ built-ins cannot bound one argument against another)`;
218
212
  case 'in':
219
213
  return `value allowlist on ${describeSelector(cond.selector)} (arg allowlist)`;
220
214
  case 'eq_seq':
@@ -227,10 +221,6 @@ function describeCondition(cond) {
227
221
  case 'compare': {
228
222
  const s = cond.compare.selector;
229
223
  switch (s.kind) {
230
- case 'oracle_price':
231
- return `oracle price condition on ${s.asset} (oracle price not supported in week-1)`;
232
- case 'invocation_count':
233
- return `invocation-count window (${s.windowSeconds}s) condition (not supported in week-1)`;
234
224
  case 'window_spent':
235
225
  return `spend-window comparison with operator '${cond.compare.operator}' (only 'lte' lowers to spending_limit)`;
236
226
  case 'amount':
@@ -264,10 +254,6 @@ function describeSelector(s) {
264
254
  return `amount(${s.token})`;
265
255
  case 'window_spent':
266
256
  return `window_spent(${s.token})`;
267
- case 'oracle_price':
268
- return `oracle_price(${s.asset})`;
269
- case 'invocation_count':
270
- return `invocation_count(${s.windowSeconds}s)`;
271
257
  case 'calldata':
272
258
  return `calldata[${s.offset}:${s.offset + s.length}]`;
273
259
  default:
@@ -1,4 +1,4 @@
1
- export type ErrorCode = 'RECORDING_FAILED' | 'RECORDING_VALIDATION_FAILED' | 'SCOPE_UNRESOLVED' | 'SYNTHESIS_ERROR' | 'MALFORMED_PREDICATE' | 'SIMULATION_ERROR' | 'VERIFICATION_FAILED' | 'DENY_CASE_FAILURE' | 'PERMIT_CASE_FAILED' | 'SUMMARY_DRIFT' | 'INSTALL_BUILD_FAILED' | 'INSTALL_CONFIRM_MISSING' | 'INSTALL_CONFIRM_EXPIRED' | 'REVOKE_BUILD_FAILED' | 'REVOKE_CONFIRM_MISSING' | 'USER_REJECTED_SIGN' | 'WALLET_TIMEOUT' | 'WALLET_UNAVAILABLE' | 'PREDICATE_TOO_LARGE' | 'PREDICATE_TOO_DEEP' | 'TOO_MANY_LEAVES' | 'IN_OPERAND_LIMIT' | 'PREDICATE_ORACLE_OVER_LIMIT' | 'POLICY_CAP_EXCEEDED' | 'WASM_TOO_LARGE' | 'MASTER_AUTH_REQUIRED' | 'NONCE_REPLAY' | 'VERSION_MISMATCH' | 'ARITHMETIC_OVERFLOW' | 'AMOUNT_OVERFLOW' | 'RULE_SIGNERS_CHANGED' | 'SCOPE_SELF_CALL' | 'ARG_MISMATCH' | 'CONTRACT_SCOPE' | 'UNSUPPORTED_NODE' | 'STATEFUL_BOUND' | 'NOT_IN_ALLOWLIST' | 'FREQUENCY' | 'SLIPPAGE_FLOOR' | 'ORACLE_STALE' | 'ORACLE_MISSING' | 'ORACLE_NO_CONFIRMATION' | 'ORACLE_DEVIATION_EXCEEDED' | 'ORACLE_MALFORMED_HISTORY' | 'ORACLE_FINGERPRINT_DRIFT' | 'ORACLE_PAUSED' | 'ORACLE_LEAF_INVALID_POSITION' | 'ORACLE_PARAMS_OUT_OF_RANGE' | 'ORACLE_DECIMALS_MISMATCH' | 'ORACLE_THRESHOLD_DECIMALS_OUT_OF_RANGE' | 'ORACLE_THRESHOLD_BASIS_REQUIRED' | 'COMPILE_OK' | 'COMPILE_GATE_FAILED';
1
+ export type ErrorCode = 'RECORDING_FAILED' | 'RECORDING_VALIDATION_FAILED' | 'SCOPE_UNRESOLVED' | 'SYNTHESIS_ERROR' | 'MALFORMED_PREDICATE' | 'SIMULATION_ERROR' | 'VERIFICATION_FAILED' | 'DENY_CASE_FAILURE' | 'PERMIT_CASE_FAILED' | 'SUMMARY_DRIFT' | 'INSTALL_BUILD_FAILED' | 'INSTALL_CONFIRM_MISSING' | 'INSTALL_CONFIRM_EXPIRED' | 'REVOKE_BUILD_FAILED' | 'REVOKE_CONFIRM_MISSING' | 'USER_REJECTED_SIGN' | 'WALLET_TIMEOUT' | 'WALLET_UNAVAILABLE' | 'PREDICATE_TOO_LARGE' | 'PREDICATE_TOO_DEEP' | 'TOO_MANY_LEAVES' | 'IN_OPERAND_LIMIT' | 'POLICY_CAP_EXCEEDED' | 'WASM_TOO_LARGE' | 'MASTER_AUTH_REQUIRED' | 'NONCE_REPLAY' | 'VERSION_MISMATCH' | 'ARITHMETIC_OVERFLOW' | 'AMOUNT_OVERFLOW' | 'RULE_SIGNERS_CHANGED' | 'SCOPE_SELF_CALL' | 'ARG_MISMATCH' | 'CONTRACT_SCOPE' | 'UNSUPPORTED_NODE' | 'STATEFUL_BOUND' | 'NOT_IN_ALLOWLIST' | 'COMPILE_OK' | 'COMPILE_GATE_FAILED';
2
2
  export interface ToolError {
3
3
  code: ErrorCode;
4
4
  message: string;
@@ -1,11 +1,8 @@
1
- export * from './adapters/oz/index.ts';
2
1
  export * from './errors.ts';
3
- export * from './ir/index.ts';
4
- export * from './mandate/index.ts';
5
2
  export * from './predicate/index.ts';
6
3
  export * from './record/index.ts';
7
4
  export * from './registry/index.ts';
8
5
  export * from './review-card/index.ts';
9
- export * from './seams/index.ts';
6
+ export * from './simulate/index.ts';
10
7
  export * from './synth/index.ts';
11
8
  export * from './types.ts';
package/dist-cjs/index.js CHANGED
@@ -14,14 +14,11 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./adapters/oz/index.js"), exports);
18
17
  __exportStar(require("./errors.js"), exports);
19
- __exportStar(require("./ir/index.js"), exports);
20
- __exportStar(require("./mandate/index.js"), exports);
21
18
  __exportStar(require("./predicate/index.js"), exports);
22
19
  __exportStar(require("./record/index.js"), exports);
23
20
  __exportStar(require("./registry/index.js"), exports);
24
21
  __exportStar(require("./review-card/index.js"), exports);
25
- __exportStar(require("./seams/index.js"), exports);
22
+ __exportStar(require("./simulate/index.js"), exports);
26
23
  __exportStar(require("./synth/index.js"), exports);
27
24
  __exportStar(require("./types.js"), exports);
@@ -8,8 +8,8 @@ export interface BuildAddContextRuleArgs {
8
8
  * admin session. The deployer signs the install call via the admin rule
9
9
  * already on the account, which is separate from this list. */
10
10
  signers: SignerDraft[];
11
- /** The policy(ies) to attach to the new rule. Only `interpreter` refs
12
- * reach the wire today; `oz_builtin` is reserved for Phase 06 follow-ups. */
11
+ /** The policy(ies) to attach to the new rule. `interpreter` is the only
12
+ * kind: the OpenZeppelin built-in backend was removed. */
13
13
  policies: PolicyRef[];
14
14
  /** Per-policy install nonce; 1 for a fresh install. */
15
15
  installNonce: number;
@@ -19,19 +19,11 @@ export interface BuildAddContextRuleArgs {
19
19
  encodedPredicate: string;
20
20
  /** Hex sha256 of the canonical predicate XDR bytes. */
21
21
  predicateHash: string;
22
- /** Per-policy oracle overrides. Absent on any key uses the wasm default. */
23
- oracleParams?: {
24
- maxStalenessSeconds?: number;
25
- maxDeviationBps?: number;
26
- /** Bound between the primary and secondary feeds. Tighten-only against
27
- * the wasm default, like the other two. */
28
- maxCrossFeedDeviationBps?: number;
29
- };
30
22
  /** Hard pin to the interpreter's wasm grammar. Refusing here fails closed
31
23
  * before the chain does; the contract will refuse a mismatch again. */
32
24
  grammarVersion?: number;
33
25
  }
34
- export declare const DEFAULT_GRAMMAR_VERSION: 1;
26
+ export declare const DEFAULT_GRAMMAR_VERSION: 3;
35
27
  /** The verb `add_context_rule` takes on the wire. */
36
28
  export declare const ADD_CONTEXT_RULE_SYMBOL: "add_context_rule";
37
29
  /** Tuple of `ScVal` arguments to pass to `Operation.invokeHostFunction` for
@@ -46,11 +38,3 @@ export type AddContextRuleArgs = readonly [
46
38
  /** Build the `add_context_rule` invocation args. Throws a `ToolError`-shaped
47
39
  * error on limit breaches or malformed input. */
48
40
  export declare function buildAddContextRuleArgs(draft: ContextRuleDraft, args: BuildAddContextRuleArgs): AddContextRuleArgs;
49
- /** The `PolicyInstallParams` ScVal an interpreter policy receives.
50
- *
51
- * Exported so the merge remedy can re-install a policy through `add_policy`
52
- * using the SAME encoder as a fresh install. Re-implementing it would risk
53
- * exactly the drift this file warns about: the field order is ABI-significant
54
- * and a differing encoding yields a rule that denies every call. */
55
- export type PolicyInstallParamArgs = Pick<BuildAddContextRuleArgs, 'encodedPredicate' | 'predicateHash' | 'installNonce' | 'oracleParams' | 'grammarVersion'>;
56
- export declare function encodePolicyInstallParams(args: PolicyInstallParamArgs): xdr.ScVal;
@@ -50,11 +50,10 @@
50
50
  Object.defineProperty(exports, "__esModule", { value: true });
51
51
  exports.ADD_CONTEXT_RULE_SYMBOL = exports.DEFAULT_GRAMMAR_VERSION = void 0;
52
52
  exports.buildAddContextRuleArgs = buildAddContextRuleArgs;
53
- exports.encodePolicyInstallParams = encodePolicyInstallParams;
54
53
  const node_crypto_1 = require("node:crypto");
55
54
  const stellar_sdk_1 = require("@stellar/stellar-sdk");
56
55
  const types_ts_1 = require("../types.js");
57
- exports.DEFAULT_GRAMMAR_VERSION = 1;
56
+ exports.DEFAULT_GRAMMAR_VERSION = types_ts_1.GRAMMAR_VERSION;
58
57
  /** The verb `add_context_rule` takes on the wire. */
59
58
  exports.ADD_CONTEXT_RULE_SYMBOL = 'add_context_rule';
60
59
  /** Build the `add_context_rule` invocation args. Throws a `ToolError`-shaped
@@ -70,15 +69,6 @@ function buildAddContextRuleArgs(draft, args) {
70
69
  if (args.signers.length === 0 && args.policies.length === 0) {
71
70
  throw limitError('INSTALL_BUILD_FAILED', 'a rule with no signers and no policies is refused at install (NoSignersAndPolicies)');
72
71
  }
73
- // OZ's spending_limit caps spend on the CONTEXT CONTRACT - it takes no
74
- // token argument - so it refuses a Default rule on chain with a bare
75
- // #3227. Say which rule shape it needs here, before the encoding, rather
76
- // than letting the user read a numeric trap.
77
- if (args.policies.some((p) => p.kind === 'oz_builtin' && p.primitive.primitive === 'spending_limit')) {
78
- if (draft.contextRuleType.kind !== 'call_contract') {
79
- throw limitError('INSTALL_BUILD_FAILED', `spending_limit caps spend on the rule's context contract, so the rule must be call_contract-scoped to that token - a "${draft.contextRuleType.kind}" rule is refused on chain (#3227)`);
80
- }
81
- }
82
72
  // ---- 2. context_type encoding ----
83
73
  const contextType = encodeContextRuleType(draft.contextRuleType);
84
74
  // ---- 3. name (string) + valid_until (Option<u32>) ----
@@ -100,15 +90,6 @@ const POLICY_INSTALL_PARAM_FIELDS = [
100
90
  'install_nonce',
101
91
  'predicate',
102
92
  'predicate_hash',
103
- 'oracle_max_staleness_seconds',
104
- 'oracle_max_deviation_bps',
105
- // Cross-feed divergence bound. A field added to the contract's
106
- // `PolicyInstallParams` changes the ABI: the host unpacks the map by field
107
- // count, so omitting one fails the entire install with
108
- // `Error(Object, UnexpectedSize)` and no indication of which field is
109
- // missing. The Rust tests build that struct in Rust and never cross this
110
- // boundary, so only a real install against a deployed contract catches it.
111
- 'oracle_max_xfeed_dev_bps',
112
93
  ];
113
94
  function encodeContextRuleType(rule) {
114
95
  switch (rule.kind) {
@@ -150,75 +131,10 @@ function encodePoliciesMap(args) {
150
131
  val: encodePolicyInstallParams(args),
151
132
  }));
152
133
  }
153
- else if (ref.kind === 'oz_builtin') {
154
- entries.push(new stellar_sdk_1.xdr.ScMapEntry({
155
- key: stellar_sdk_1.Address.fromString(ref.instanceAddress).toScVal(),
156
- val: encodeOzPrimitiveParams(ref.primitive),
157
- }));
158
- }
159
134
  }
160
135
  entries.sort(sortByScValSymbolString);
161
136
  return stellar_sdk_1.xdr.ScVal.scvMap(entries);
162
137
  }
163
- /** Encode the install params for one OZ built-in policy.
164
- *
165
- * Field names and types are read from the deployed contracts' own spec:
166
- * SpendingLimitAccountParams { period_ledgers: u32, spending_limit: i128 }
167
- * SimpleThresholdAccountParams { threshold: u32 }
168
- * WeightedThresholdAccountParams { signer_weights: map, threshold: u32 }
169
- * Entries are symbol-string ordered for the same reason the interpreter's
170
- * are: the host orders by symbol, not by XDR bytes.
171
- */
172
- function encodeOzPrimitiveParams(primitive) {
173
- const entries = [];
174
- const push = (name, val) => entries.push(new stellar_sdk_1.xdr.ScMapEntry({ key: stellar_sdk_1.xdr.ScVal.scvSymbol(name), val }));
175
- const p = primitive.params;
176
- switch (primitive.primitive) {
177
- case 'spending_limit': {
178
- const limit = p.spending_limit;
179
- const period = p.period_ledgers;
180
- if (typeof limit !== 'string' || typeof period !== 'number') {
181
- throw limitError('INSTALL_BUILD_FAILED', 'spending_limit needs { spending_limit: string; period_ledgers: number }');
182
- }
183
- push('period_ledgers', stellar_sdk_1.xdr.ScVal.scvU32(period));
184
- push('spending_limit', encodeI128(limit));
185
- break;
186
- }
187
- case 'simple_threshold': {
188
- const threshold = p.threshold;
189
- if (typeof threshold !== 'number') {
190
- throw limitError('INSTALL_BUILD_FAILED', 'simple_threshold needs { threshold: number }');
191
- }
192
- push('threshold', stellar_sdk_1.xdr.ScVal.scvU32(threshold));
193
- break;
194
- }
195
- case 'weighted_threshold': {
196
- const threshold = p.threshold;
197
- const weights = p.weights;
198
- if (typeof threshold !== 'number' || !weights) {
199
- throw limitError('INSTALL_BUILD_FAILED', 'weighted_threshold needs { threshold: number; weights: Record<address, number> }');
200
- }
201
- const weightEntries = Object.entries(weights)
202
- .map(([addr, w]) => new stellar_sdk_1.xdr.ScMapEntry({
203
- key: stellar_sdk_1.Address.fromString(addr).toScVal(),
204
- val: stellar_sdk_1.xdr.ScVal.scvU32(w),
205
- }))
206
- .sort((a, b) => (a.key().toXDR('base64') < b.key().toXDR('base64') ? -1 : 1));
207
- push('signer_weights', stellar_sdk_1.xdr.ScVal.scvMap(weightEntries));
208
- push('threshold', stellar_sdk_1.xdr.ScVal.scvU32(threshold));
209
- break;
210
- }
211
- }
212
- entries.sort((a, b) => sortBySymbolString(a.key(), b.key()));
213
- return stellar_sdk_1.xdr.ScVal.scvMap(entries);
214
- }
215
- function encodeI128(value) {
216
- const v = BigInt(value);
217
- return stellar_sdk_1.xdr.ScVal.scvI128(new stellar_sdk_1.xdr.Int128Parts({
218
- hi: new stellar_sdk_1.xdr.Int64(BigInt.asIntN(64, v >> 64n)),
219
- lo: new stellar_sdk_1.xdr.Uint64(BigInt.asUintN(64, v)),
220
- }));
221
- }
222
138
  function encodePolicyInstallParams(args) {
223
139
  const predicate = Buffer.from(args.encodedPredicate, 'base64');
224
140
  const computedHash = (0, node_crypto_1.createHash)('sha256').update(predicate).digest('hex');
@@ -228,15 +144,11 @@ function encodePolicyInstallParams(args) {
228
144
  // Per-field value encoders. Each entry returns the ScVal to drop into the
229
145
  // map; the key symbol comes from the surrounding loop. Adding a field is
230
146
  // one row here plus the symbol in POLICY_INSTALL_PARAM_FIELDS.
231
- const oracleParams = args.oracleParams;
232
147
  const valueFor = {
233
148
  grammar_version: () => stellar_sdk_1.xdr.ScVal.scvU32(args.grammarVersion ?? exports.DEFAULT_GRAMMAR_VERSION),
234
149
  install_nonce: () => stellar_sdk_1.xdr.ScVal.scvU32(args.installNonce),
235
150
  predicate: () => stellar_sdk_1.xdr.ScVal.scvBytes(predicate),
236
151
  predicate_hash: () => stellar_sdk_1.xdr.ScVal.scvBytes(Buffer.from(args.predicateHash, 'hex')),
237
- oracle_max_staleness_seconds: () => encodeOptionU32(oracleParams?.maxStalenessSeconds),
238
- oracle_max_deviation_bps: () => encodeOptionU32(oracleParams?.maxDeviationBps),
239
- oracle_max_xfeed_dev_bps: () => encodeOptionU32(oracleParams?.maxCrossFeedDeviationBps),
240
152
  };
241
153
  const entries = POLICY_INSTALL_PARAM_FIELDS.map((k) => new stellar_sdk_1.xdr.ScMapEntry({ key: stellar_sdk_1.xdr.ScVal.scvSymbol(k), val: valueFor[k]() }));
242
154
  // The host orders map entries by the SYMBOL STRING, not by XDR bytes. A
@@ -246,14 +158,6 @@ function encodePolicyInstallParams(args) {
246
158
  entries.sort((a, b) => sortBySymbolString(a.key(), b.key()));
247
159
  return stellar_sdk_1.xdr.ScVal.scvMap(entries);
248
160
  }
249
- function encodeOptionU32(v) {
250
- if (v === undefined)
251
- return stellar_sdk_1.xdr.ScVal.scvVoid();
252
- if (!Number.isFinite(v) || v < 0 || v > 0xffffffff) {
253
- throw limitError('INSTALL_BUILD_FAILED', `oracle params value ${v} is outside u32 range`);
254
- }
255
- return stellar_sdk_1.xdr.ScVal.scvU32(v);
256
- }
257
161
  /** Sort host-map keys by their symbol-string form. The host orders map
258
162
  * entries by the SYMBOL STRING, not by the key's XDR bytes (a length
259
163
  * prefix in the encoding would otherwise put `amount` before `address`).
@@ -1,5 +1,5 @@
1
- import { Contract, rpc, type Transaction } from '@stellar/stellar-sdk';
2
- import { DEFAULT_GRAMMAR_VERSION } from './build-add-context-rule.ts';
1
+ import { rpc, type Transaction } from '@stellar/stellar-sdk';
2
+ import type { ContextRuleDraft } from '../types.ts';
3
3
  /** Minimal Soroban RPC surface the install pipeline needs. Test seams
4
4
  * inject a stub so the builder stays deterministic; production builds
5
5
  * the real one via `createRpcServer` from `../record/rpc.ts`. */
@@ -31,20 +31,14 @@ export interface BuildInstallPolicyArgs {
31
31
  sourceAccount: string;
32
32
  /** Network passphrase - pins the hash the auth digest binds. */
33
33
  networkPassphrase: string;
34
- /** The new rule to install. Mirrors the core `ContextRuleDraft`. */
35
- rule: BuildInstallPolicyRuleDraft;
34
+ /** The new rule to install. */
35
+ rule: ContextRuleDraft;
36
36
  /** Per-rule install nonce; 1 for a fresh install. */
37
37
  installNonce: number;
38
38
  /** Already-encoded (base64) canonical ScVal of the predicate. */
39
39
  encodedPredicate: string;
40
40
  /** Hex sha256 of the canonical predicate XDR bytes. */
41
41
  predicateHash: string;
42
- /** Per-policy oracle overrides. */
43
- oracleParams?: {
44
- maxStalenessSeconds?: number;
45
- maxDeviationBps?: number;
46
- maxCrossFeedDeviationBps?: number;
47
- };
48
42
  /** Grammar version override; defaults to 1. */
49
43
  grammarVersion?: number;
50
44
  /** Base fee in stroops; defaults to BASE_FEE (100). */
@@ -54,41 +48,6 @@ export interface BuildInstallPolicyArgs {
54
48
  /** Ledger window (in ledgers) for the auth entry's `validUntil`. */
55
49
  authValidUntilLedgers?: number;
56
50
  }
57
- export type BuildInstallPolicyRuleDraft = {
58
- contextRuleType: {
59
- kind: 'default';
60
- } | {
61
- kind: 'call_contract';
62
- contract: string;
63
- } | {
64
- kind: 'create_contract';
65
- wasmHash: string;
66
- };
67
- name: string;
68
- validUntilLedger: number | null;
69
- signers: BuildInstallPolicySignerDraft[];
70
- policies: BuildInstallPolicyPolicyRef[];
71
- };
72
- export type BuildInstallPolicySignerDraft = {
73
- kind: 'delegated';
74
- address: string;
75
- } | {
76
- kind: 'external';
77
- verifier: string;
78
- keyBytes: string;
79
- };
80
- export type BuildInstallPolicyPolicyRef = {
81
- kind: 'interpreter';
82
- interpreterAddress: string;
83
- predicateBlobBase64: string;
84
- } | {
85
- kind: 'oz_builtin';
86
- instanceAddress: string;
87
- primitive: {
88
- primitive: 'spending_limit' | 'simple_threshold' | 'weighted_threshold';
89
- params: Record<string, unknown>;
90
- };
91
- };
92
51
  /** Human-readable description of the install call, decoded FROM the built
93
52
  * XDR (not from the input args). The XDR is the source of truth: a
94
53
  * human approving a review card needs the description to mirror the bytes
@@ -134,10 +93,6 @@ export interface InstallCallDescribes {
134
93
  installNonce: number;
135
94
  predicateHash: string;
136
95
  predicateSha256OfEmbeddedBytes: string;
137
- } | {
138
- kind: 'oz_builtin';
139
- address: string;
140
- primitive: 'spending_limit' | 'simple_threshold' | 'weighted_threshold';
141
96
  }>;
142
97
  /** The install nonce, decoded from the interpreter policy's
143
98
  * `install_nonce` field. Echoed at the top level for reviewer convenience;
@@ -217,7 +172,3 @@ export interface BuildRevokePolicyResult {
217
172
  authValidUntilLedger: number;
218
173
  rootInvocationXdr: string;
219
174
  }
220
- /** Re-export so the run-layer does not need to import from
221
- * build-add-context-rule.ts (keeps the install/ -> install/ dependency
222
- * direction intact). */
223
- export { Contract, DEFAULT_GRAMMAR_VERSION };
@@ -18,15 +18,12 @@
18
18
  // forwards each install_param to that policy, so the interpreter stores the
19
19
  // predicate document as part of this same transaction.
20
20
  Object.defineProperty(exports, "__esModule", { value: true });
21
- exports.DEFAULT_GRAMMAR_VERSION = exports.Contract = void 0;
22
21
  exports.rpcClientFromServer = rpcClientFromServer;
23
22
  exports.buildInstallPolicyXdr = buildInstallPolicyXdr;
24
23
  exports.buildRevokePolicyXdr = buildRevokePolicyXdr;
25
24
  const node_crypto_1 = require("node:crypto");
26
25
  const stellar_sdk_1 = require("@stellar/stellar-sdk");
27
- Object.defineProperty(exports, "Contract", { enumerable: true, get: function () { return stellar_sdk_1.Contract; } });
28
26
  const build_add_context_rule_ts_1 = require("./build-add-context-rule.js");
29
- Object.defineProperty(exports, "DEFAULT_GRAMMAR_VERSION", { enumerable: true, get: function () { return build_add_context_rule_ts_1.DEFAULT_GRAMMAR_VERSION; } });
30
27
  const oz_auth_ts_1 = require("./oz-auth.js");
31
28
  /** Convert a real rpc.Server into the InstallRpcClient surface. The
32
29
  * `getContractVersion` lookup uses `simulateTransaction` against
@@ -47,7 +44,7 @@ function rpcClientFromServer(server, networkPassphrase) {
47
44
  // random key does NOT exist on chain - asking the network for it returns
48
45
  // 404 and the version probe fails for a reason that has nothing to do
49
46
  // with the contract being probed.
50
- const account = new stellar_sdk_2.Account(stellar_sdk_1.Keypair.random().publicKey(), '0');
47
+ const account = new stellar_sdk_1.Account(stellar_sdk_1.Keypair.random().publicKey(), '0');
51
48
  const tx = new stellar_sdk_1.TransactionBuilder(account, {
52
49
  fee: stellar_sdk_1.BASE_FEE,
53
50
  networkPassphrase,
@@ -80,73 +77,21 @@ async function buildInstallPolicyXdr(args) {
80
77
  name: args.rule.name,
81
78
  validUntilLedger: args.rule.validUntilLedger,
82
79
  signers: args.rule.signers,
83
- policies: args.rule.policies.map(adaptPolicyRef),
80
+ policies: args.rule.policies,
84
81
  }, {
85
82
  signers: args.rule.signers,
86
- policies: args.rule.policies.map(adaptPolicyRef),
83
+ policies: args.rule.policies,
87
84
  installNonce: args.installNonce,
88
85
  encodedPredicate: args.encodedPredicate,
89
86
  predicateHash: args.predicateHash,
90
- ...(args.oracleParams ? { oracleParams: args.oracleParams } : {}),
91
87
  ...(args.grammarVersion !== undefined ? { grammarVersion: args.grammarVersion } : {}),
92
88
  });
93
- // 2. Fetch the source sequence, then build the recording transaction with a
94
- // bare host call. The recording pass assigns the smart-account auth nonce
95
- // and root invocation needed to construct OZ's AuthPayload.
96
- const source = await args.rpc.getAccount(args.sourceAccount);
97
- const hostFunction = stellar_sdk_1.xdr.HostFunction.hostFunctionTypeInvokeContract(new stellar_sdk_1.xdr.InvokeContractArgs({
98
- contractAddress: new stellar_sdk_1.Address(args.smartAccount).toScAddress(),
99
- functionName: 'add_context_rule',
100
- args: [...callArgs],
101
- }));
102
- const makeOperation = (auth = []) => stellar_sdk_1.Operation.invokeHostFunction({ func: hostFunction, auth });
103
- const baseFee = args.baseFee !== undefined ? String(args.baseFee) : stellar_sdk_1.BASE_FEE;
104
- const buildTx = (op) => buildUnsignedTx({
105
- sourceAccount: args.sourceAccount,
106
- sequence: source.sequenceNumber(),
107
- fee: baseFee,
108
- networkPassphrase: args.networkPassphrase,
109
- op,
110
- });
111
- const recordingTx = buildTx(makeOperation());
112
- // 3. Recording simulation: capture the smart account's nonce and invocation
113
- // tree. Nothing is signed here.
114
- const recorded = await args.rpc.simulateTransaction(recordingTx);
115
- if (stellar_sdk_1.rpc.Api.isSimulationError(recorded)) {
116
- // Short, stable reason. The full `simulateTransaction` error (which
117
- // carries host + URL detail) stays in the SDK's own logs - never
118
- // reflected back into a user-facing message where it would
119
- // reconnoitre the RPC.
120
- throw new Error('install_policy: simulateTransaction failed');
121
- }
122
- const original = (recorded.result?.auth ?? []).find((entry) => entry.credentials().switch().name === 'sorobanCredentialsAddress' &&
123
- stellar_sdk_1.Address.fromScAddress(entry.credentials().address().address()).toString() ===
124
- args.smartAccount);
125
- if (!original) {
126
- throw new Error(`install_policy: no Soroban auth entry for smart account ${args.smartAccount}; this call does not route through the smart account`);
127
- }
128
- // 4. `add_context_rule` is authorised by the deploy-time admin rule (rule 0).
89
+ // 2. `add_context_rule` is authorised by the deploy-time admin rule (rule 0).
129
90
  // The delegated signer uses source-account credentials, so its signature
130
91
  // bytes stay empty and the ordinary transaction-envelope signature covers
131
92
  // the call when the consumer signs it.
132
- const validUntilLedger = (await args.rpc.getLatestLedger()).sequence +
133
- (args.authValidUntilLedgers ?? DEFAULT_AUTH_VALID_UNTIL_LEDGERS);
134
- const contextRuleIds = [0];
135
- const digest = (0, oz_auth_ts_1.authDigest)((0, oz_auth_ts_1.signaturePayload)(args.networkPassphrase, original.credentials().address().nonce(), validUntilLedger, original.rootInvocation()), contextRuleIds);
136
- const authEntries = [
137
- (0, oz_auth_ts_1.accountEntry)(original, validUntilLedger, (0, oz_auth_ts_1.authPayload)([args.sourceAccount], contextRuleIds, () => Buffer.alloc(0))),
138
- ...contextRuleIds.map(() => (0, oz_auth_ts_1.delegatedSignerEntry)(args.smartAccount, digest)),
139
- ];
140
- // 5. Simulate again with the OZ entries already attached. The SDK preserves
141
- // existing auth during assembly and adds the simulated Soroban footprint +
142
- // resource fee, yielding a complete unsigned envelope.
143
- const txWithAuth = buildTx(makeOperation(authEntries));
144
- const enforcing = await args.rpc.simulateTransaction(txWithAuth);
145
- if (stellar_sdk_1.rpc.Api.isSimulationError(enforcing)) {
146
- throw new Error('install_policy: auth simulateTransaction failed');
147
- }
148
- const finalTx = stellar_sdk_1.rpc.assembleTransaction(txWithAuth, enforcing).build();
149
- // 6. Decode the structured description FROM the final assembled transaction.
93
+ const { finalTx, original, validUntilLedger } = await buildAuthorisedSmartAccountTx(args, 'add_context_rule', [...callArgs], 'install_policy');
94
+ // 3. Decode the structured description FROM the final assembled transaction.
150
95
  // The human approval binds to the exact bytes the wallet will sign.
151
96
  const describes = decodeInstallCallDescribes(finalTx, args.installNonce);
152
97
  return {
@@ -172,11 +117,39 @@ async function buildInstallPolicyXdr(args) {
172
117
  * deployer can revoke. This builder does not pre-check the signer: it would
173
118
  * be guessing at a contract it cannot read, and the chain is the authority. */
174
119
  async function buildRevokePolicyXdr(args) {
120
+ // Removal is master-only, so the deploy-time admin rule authorises it. The
121
+ // recorded rootInvocation still includes remove_context_rule(ruleId), binding
122
+ // the auth payload to the exact rule being removed. As with install,
123
+ // source-account credentials carry the delegated signer entry and the
124
+ // consumer supplies only the ordinary envelope signature.
125
+ const { finalTx, original, validUntilLedger } = await buildAuthorisedSmartAccountTx(args, 'remove_context_rule', [stellar_sdk_1.xdr.ScVal.scvU32(args.ruleId)], 'revoke_policy');
126
+ return {
127
+ unsignedXdr: finalTx.toEnvelope().toXDR().toString('base64'),
128
+ smartAccount: args.smartAccount,
129
+ sourceAccount: args.sourceAccount,
130
+ call: { contract: args.smartAccount, fn: 'remove_context_rule', ruleId: args.ruleId },
131
+ authNonce: original.credentials().address().nonce().toString(),
132
+ authValidUntilLedger: validUntilLedger,
133
+ rootInvocationXdr: original.rootInvocation().toXDR().toString('base64'),
134
+ };
135
+ }
136
+ /** ~25 minutes at 5s/ledger. */
137
+ const DEFAULT_AUTH_VALID_UNTIL_LEDGERS = 300;
138
+ // ---- internals ----
139
+ /** Record a bare call to the smart account, attach the deploy-time admin rule's
140
+ * auth entries, and re-simulate to assemble the footprint.
141
+ *
142
+ * Install and revoke differ only in the call they wrap, so they share this
143
+ * spine: the recording pass supplies the auth nonce and root invocation OZ's
144
+ * AuthPayload binds to, and the second simulation adds the Soroban footprint +
145
+ * resource fee. Nothing here is signed. `errorPrefix` names the calling tool in
146
+ * the fail-closed messages so a caller can still tell which call failed. */
147
+ async function buildAuthorisedSmartAccountTx(args, functionName, callArgs, errorPrefix) {
175
148
  const source = await args.rpc.getAccount(args.sourceAccount);
176
149
  const hostFunction = stellar_sdk_1.xdr.HostFunction.hostFunctionTypeInvokeContract(new stellar_sdk_1.xdr.InvokeContractArgs({
177
150
  contractAddress: new stellar_sdk_1.Address(args.smartAccount).toScAddress(),
178
- functionName: 'remove_context_rule',
179
- args: [stellar_sdk_1.xdr.ScVal.scvU32(args.ruleId)],
151
+ functionName,
152
+ args: callArgs,
180
153
  }));
181
154
  const makeOperation = (auth = []) => stellar_sdk_1.Operation.invokeHostFunction({ func: hostFunction, auth });
182
155
  const baseFee = args.baseFee !== undefined ? String(args.baseFee) : stellar_sdk_1.BASE_FEE;
@@ -193,19 +166,14 @@ async function buildRevokePolicyXdr(args) {
193
166
  // carries host + URL detail) stays in the SDK's own logs - never
194
167
  // reflected back into a user-facing message where it would
195
168
  // reconnoitre the RPC.
196
- throw new Error('revoke_policy: simulateTransaction failed');
169
+ throw new Error(`${errorPrefix}: simulateTransaction failed`);
197
170
  }
198
171
  const original = (recorded.result?.auth ?? []).find((entry) => entry.credentials().switch().name === 'sorobanCredentialsAddress' &&
199
172
  stellar_sdk_1.Address.fromScAddress(entry.credentials().address().address()).toString() ===
200
173
  args.smartAccount);
201
174
  if (!original) {
202
- throw new Error(`revoke_policy: no Soroban auth entry for smart account ${args.smartAccount}; this call does not route through the smart account`);
175
+ throw new Error(`${errorPrefix}: no Soroban auth entry for smart account ${args.smartAccount}; this call does not route through the smart account`);
203
176
  }
204
- // Removal is master-only, so the deploy-time admin rule authorises it. The
205
- // recorded rootInvocation still includes remove_context_rule(ruleId), binding
206
- // the auth payload to the exact rule being removed. As with install,
207
- // source-account credentials carry the delegated signer entry and the
208
- // consumer supplies only the ordinary envelope signature.
209
177
  const validUntilLedger = (await args.rpc.getLatestLedger()).sequence +
210
178
  (args.authValidUntilLedgers ?? DEFAULT_AUTH_VALID_UNTIL_LEDGERS);
211
179
  const contextRuleIds = [0];
@@ -217,38 +185,12 @@ async function buildRevokePolicyXdr(args) {
217
185
  const txWithAuth = buildTx(makeOperation(authEntries));
218
186
  const enforcing = await args.rpc.simulateTransaction(txWithAuth);
219
187
  if (stellar_sdk_1.rpc.Api.isSimulationError(enforcing)) {
220
- throw new Error('revoke_policy: auth simulateTransaction failed');
221
- }
222
- const finalTx = stellar_sdk_1.rpc.assembleTransaction(txWithAuth, enforcing).build();
223
- return {
224
- unsignedXdr: finalTx.toEnvelope().toXDR().toString('base64'),
225
- smartAccount: args.smartAccount,
226
- sourceAccount: args.sourceAccount,
227
- call: { contract: args.smartAccount, fn: 'remove_context_rule', ruleId: args.ruleId },
228
- authNonce: original.credentials().address().nonce().toString(),
229
- authValidUntilLedger: validUntilLedger,
230
- rootInvocationXdr: original.rootInvocation().toXDR().toString('base64'),
231
- };
232
- }
233
- /** ~25 minutes at 5s/ledger. */
234
- const DEFAULT_AUTH_VALID_UNTIL_LEDGERS = 300;
235
- // ---- internals ----
236
- /** Adapter: turn the install-policy wire `PolicyRef` shape into the core
237
- * `PolicyRef` shape `buildAddContextRuleArgs` expects. Keeps the wire
238
- * schema hand-rolled + flat (the strict union would need a recursive
239
- * schema) while delegating to the proven encoder for the actual bytes. */
240
- function adaptPolicyRef(p) {
241
- if (p.kind === 'interpreter') {
242
- return {
243
- kind: 'interpreter',
244
- interpreterAddress: p.interpreterAddress,
245
- predicateBlobBase64: p.predicateBlobBase64,
246
- };
188
+ throw new Error(`${errorPrefix}: auth simulateTransaction failed`);
247
189
  }
248
190
  return {
249
- kind: 'oz_builtin',
250
- instanceAddress: p.instanceAddress,
251
- primitive: p.primitive,
191
+ finalTx: stellar_sdk_1.rpc.assembleTransaction(txWithAuth, enforcing).build(),
192
+ original,
193
+ validUntilLedger,
252
194
  };
253
195
  }
254
196
  /** Build an unsigned Soroban transaction envelope. The `sequence` is
@@ -256,7 +198,7 @@ function adaptPolicyRef(p) {
256
198
  * the SDK accepts). No signing. The returned Transaction is what
257
199
  * `simulateTransaction` accepts. */
258
200
  function buildUnsignedTx(args) {
259
- const account = new stellar_sdk_2.Account(args.sourceAccount, args.sequence);
201
+ const account = new stellar_sdk_1.Account(args.sourceAccount, args.sequence);
260
202
  const tx = new stellar_sdk_1.TransactionBuilder(account, {
261
203
  fee: args.fee,
262
204
  networkPassphrase: args.networkPassphrase,
@@ -302,14 +244,13 @@ function decodeInstallCallDescribes(tx, expectedInstallNonce) {
302
244
  if (scvArgs.length !== 5) {
303
245
  throw new Error(`install_policy: built op has ${scvArgs.length} args, expected 5 (context_type, name, valid_until, signers, policies)`);
304
246
  }
305
- const contextType = scvArgs[0];
306
247
  const nameScv = scvArgs[1];
307
248
  const validUntilScv = scvArgs[2];
308
249
  const signersScv = scvArgs[3];
309
250
  const policiesScv = scvArgs[4];
310
251
  // The length check above pins these as defined; the local references
311
252
  // satisfy noUncheckedIndexedAccess on the accessors below.
312
- if (!nameScv || !validUntilScv || !signersScv || !policiesScv || !contextType) {
253
+ if (!nameScv || !validUntilScv || !signersScv || !policiesScv) {
313
254
  throw new Error('install_policy: built op args include an undefined slot despite length check');
314
255
  }
315
256
  // name
@@ -390,7 +331,6 @@ function decodeInstallCallDescribes(tx, expectedInstallNonce) {
390
331
  fields.set(fk.sym().toString(), inner.val());
391
332
  }
392
333
  // Interpreter policy fields carry grammar_version/install_nonce/predicate.
393
- // OZ primitives carry spending_limit/period_ledgers/threshold/signers.
394
334
  if (fields.has('predicate') || fields.has('grammar_version') || fields.has('install_nonce')) {
395
335
  const installNonceScv = fields.get('install_nonce');
396
336
  if (installNonceScv?.switch().name !== 'scvU32') {
@@ -419,21 +359,6 @@ function decodeInstallCallDescribes(tx, expectedInstallNonce) {
419
359
  observedInstallNonce = installNonce;
420
360
  continue;
421
361
  }
422
- // OZ built-in primitive. Distinguish by the parameter shape we
423
- // emitted; matching one of the three primitives exactly pins the
424
- // kind we built.
425
- if (fields.has('spending_limit') && fields.has('period_ledgers')) {
426
- policies.push({ kind: 'oz_builtin', address, primitive: 'spending_limit' });
427
- continue;
428
- }
429
- if (fields.has('threshold') && fields.has('signer_weights')) {
430
- policies.push({ kind: 'oz_builtin', address, primitive: 'weighted_threshold' });
431
- continue;
432
- }
433
- if (fields.has('threshold')) {
434
- policies.push({ kind: 'oz_builtin', address, primitive: 'simple_threshold' });
435
- continue;
436
- }
437
362
  throw new Error(`install_policy: policies[${address}] value has an unknown field set; the encoder may have drifted`);
438
363
  }
439
364
  // `observedInstallNonce` is the nonce baked into whichever interpreter
@@ -462,6 +387,3 @@ function decodeInstallCallDescribes(tx, expectedInstallNonce) {
462
387
  installNonce,
463
388
  };
464
389
  }
465
- // Local re-import to avoid pulling the class from the SDK module path
466
- // at the top of the file (avoids the unused-import lint).
467
- const stellar_sdk_2 = require("@stellar/stellar-sdk");
@@ -1,3 +1 @@
1
- export { ANY, type AuthorityOverlap, type ContextType, effectiveSelectors, findAuthorityOverlaps, type IntendedInstall, intersectSelectors, type MergeResult, mergeIntoAnd, type ObservedRule, type OverlapSeverity, permittedSelectors, type RuleClass, type Selector, signerKey, } from './authority-overlap.ts';
2
1
  export { ADD_CONTEXT_RULE_SYMBOL, type AddContextRuleArgs, type BuildAddContextRuleArgs, buildAddContextRuleArgs, DEFAULT_GRAMMAR_VERSION, } from './build-add-context-rule.ts';
3
- export { type AccountRuleReader, accountRuleReaderFromServer, type CollectedRules, collectObservedRules, decodeContextRule, decodeContextType, decodeSigner, docLedgerKey, MAX_RULE_ID_SCAN, } from './read-account-rules.ts';