@crediolabs/policy-synth 0.1.5 → 0.1.6

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 (62) hide show
  1. package/dist/record/decode.js +43 -0
  2. package/dist/record/freshness.d.ts +14 -1
  3. package/dist/record/freshness.js +32 -2
  4. package/dist/record/index.d.ts +11 -0
  5. package/dist/record/index.js +25 -0
  6. package/dist/record/movements.d.ts +15 -3
  7. package/dist/record/movements.js +42 -7
  8. package/dist/run/index.d.ts +13 -1
  9. package/dist/run/index.js +76 -18
  10. package/dist/run/schemas.d.ts +13 -0
  11. package/dist/run/schemas.js +8 -0
  12. package/dist/synth/address.d.ts +7 -0
  13. package/dist/synth/address.js +12 -0
  14. package/dist/synth/compose-from-recording.d.ts +4 -3
  15. package/dist/synth/compose-from-recording.js +16 -6
  16. package/dist/synth/deny-cases.d.ts +12 -2
  17. package/dist/synth/deny-cases.js +58 -2
  18. package/dist/synth/index.d.ts +1 -0
  19. package/dist/synth/index.js +4 -0
  20. package/dist/synth/minimize.d.ts +1 -1
  21. package/dist/synth/minimize.js +3 -3
  22. package/dist/synth/synthesize-from-recording.js +54 -6
  23. package/dist/types.d.ts +24 -1
  24. package/dist-cjs/record/decode.js +43 -0
  25. package/dist-cjs/record/freshness.d.ts +14 -1
  26. package/dist-cjs/record/freshness.js +32 -2
  27. package/dist-cjs/record/index.d.ts +11 -0
  28. package/dist-cjs/record/index.js +25 -0
  29. package/dist-cjs/record/movements.d.ts +15 -3
  30. package/dist-cjs/record/movements.js +42 -7
  31. package/dist-cjs/run/index.d.ts +13 -1
  32. package/dist-cjs/run/index.js +76 -17
  33. package/dist-cjs/run/schemas.d.ts +13 -0
  34. package/dist-cjs/run/schemas.js +8 -0
  35. package/dist-cjs/synth/address.d.ts +7 -0
  36. package/dist-cjs/synth/address.js +15 -0
  37. package/dist-cjs/synth/compose-from-recording.d.ts +4 -3
  38. package/dist-cjs/synth/compose-from-recording.js +16 -6
  39. package/dist-cjs/synth/deny-cases.d.ts +12 -2
  40. package/dist-cjs/synth/deny-cases.js +60 -2
  41. package/dist-cjs/synth/index.d.ts +1 -0
  42. package/dist-cjs/synth/index.js +6 -1
  43. package/dist-cjs/synth/minimize.d.ts +1 -1
  44. package/dist-cjs/synth/minimize.js +3 -3
  45. package/dist-cjs/synth/synthesize-from-recording.js +53 -5
  46. package/dist-cjs/types.d.ts +24 -1
  47. package/package.json +1 -1
  48. package/src/contracts/policy-template/OZ_POLICY_TRAIT.md +171 -0
  49. package/src/record/corpus-fixtures.json +532 -0
  50. package/src/record/decode.ts +42 -0
  51. package/src/record/freshness.ts +34 -2
  52. package/src/record/index.ts +40 -0
  53. package/src/record/movements.ts +40 -7
  54. package/src/run/index.ts +80 -16
  55. package/src/run/schemas.ts +8 -0
  56. package/src/synth/address.ts +14 -0
  57. package/src/synth/compose-from-recording.ts +20 -9
  58. package/src/synth/deny-cases.ts +66 -2
  59. package/src/synth/index.ts +4 -0
  60. package/src/synth/minimize.ts +7 -3
  61. package/src/synth/synthesize-from-recording.ts +59 -6
  62. package/src/types.ts +18 -1
@@ -0,0 +1,171 @@
1
+ # OZ_POLICY_TRAIT.md — OpenZeppelin Stellar Accounts Pinned Trait Definitions
2
+
3
+ > **Pinned at:** `OpenZeppelin/stellar-contracts@v0.8.0-rc.3`
4
+ > **Commit SHA:** `4114bb8e2d7f090bdd9f45731e0607071d5ecea2`
5
+ > **Permalink:** https://github.com/OpenZeppelin/stellar-contracts/blob/4114bb8e2d7f090bdd9f45731e0607071d5ecea2/packages/accounts/src/policies/mod.rs
6
+ > **Policy trait file:** https://github.com/OpenZeppelin/stellar-contracts/blob/4114bb8e2d7f090bdd9f45731e0607071d5ecea2/packages/accounts/src/policies/mod.rs
7
+ > **Storage file (Signer, ContextRule, add_context_rule):** https://github.com/OpenZeppelin/stellar-contracts/blob/4114bb8e2d7f090bdd9f45731e0607071d5ecea2/packages/accounts/src/smart_account/storage.rs
8
+ > **Verified:** 2026-07-24 by W3 agent
9
+
10
+ ---
11
+
12
+ ## Policy Trait
13
+
14
+ Source: `packages/accounts/src/policies/mod.rs` (permalinked above)
15
+
16
+ ```rust
17
+ pub trait Policy {
18
+ type AccountParams: FromVal<Env, Val>;
19
+
20
+ fn enforce(
21
+ e: &Env,
22
+ context: Context,
23
+ authenticated_signers: Vec<Signer>,
24
+ context_rule: ContextRule,
25
+ smart_account: Address,
26
+ );
27
+
28
+ fn install(
29
+ e: &Env,
30
+ install_params: Self::AccountParams,
31
+ context_rule: ContextRule,
32
+ smart_account: Address,
33
+ );
34
+
35
+ fn uninstall(e: &Env, context_rule: ContextRule, smart_account: Address);
36
+ }
37
+ ```
38
+
39
+ ### Key observations
40
+
41
+ - `Policy::enforce` receives a **single `Context`** — the authorization context being enforced. It does **NOT** carry a `sub_invocations` field. Sub-invocations live under `InvokerContractAuthEntry::Contract(SubContractInvocation)` and are used for `authorize_as_current_contract`, not passed to `Policy::enforce`.
42
+ - The `Context` type is defined in `soroban_sdk::auth::Context` (external, not in this repo).
43
+ - `install` takes `Self::AccountParams` — the interpreter's `PolicyInstallParams` struct satisfies this via `FromVal` / `IntoVal`.
44
+ - `uninstall` requires the `ContextRule` to be passed by the caller; the interpreter stores it to compute the `rule_id`.
45
+
46
+ ---
47
+
48
+ ## Signer Enum
49
+
50
+ Source: `packages/accounts/src/smart_account/storage.rs` lines 148–155 (permalinked above)
51
+
52
+ ```rust
53
+ pub enum Signer {
54
+ Delegated(Address),
55
+ External(Address, Bytes),
56
+ }
57
+ ```
58
+
59
+ **Two variants only.** No `Key` variant. No `SmartAccount` variant. The verifier address + key bytes for an external signer are carried in the `External` variant itself. There is **no master/non-master discriminator** on the type.
60
+
61
+ ---
62
+
63
+ ## ContextRuleType Enum
64
+
65
+ Source: `packages/accounts/src/smart_account/storage.rs` lines 170–177
66
+
67
+ ```rust
68
+ pub enum ContextRuleType {
69
+ Default,
70
+ CallContract(Address),
71
+ CreateContract(BytesN<32>),
72
+ }
73
+ ```
74
+
75
+ ---
76
+
77
+ ## ContextRule Struct
78
+
79
+ Source: `packages/accounts/src/smart_account/storage.rs` lines 179–199
80
+
81
+ ```rust
82
+ pub struct ContextRule {
83
+ pub id: u32,
84
+ pub context_type: ContextRuleType,
85
+ pub name: String,
86
+ pub signers: Vec<Signer>,
87
+ pub signer_ids: Vec<u32>,
88
+ pub policies: Vec<Address>,
89
+ pub policy_ids: Vec<u32>,
90
+ pub valid_until: Option<u32>,
91
+ }
92
+ ```
93
+
94
+ ---
95
+
96
+ ## add_context_rule Signature
97
+
98
+ Source: `packages/accounts/src/smart_account/storage.rs` lines 620–645
99
+
100
+ ```rust
101
+ pub fn add_context_rule(
102
+ e: &Env,
103
+ context_type: &ContextRuleType,
104
+ name: &String,
105
+ valid_until: Option<u32>,
106
+ signers: &Vec<Signer>,
107
+ policies: &Map<Address, Val>,
108
+ ) -> ContextRule
109
+ ```
110
+
111
+ ### Auth requirements
112
+
113
+ - `add_context_rule` is called by the **smart account itself** (the contract owning the context rules).
114
+ - Auth is enforced by Soroban's `require_auth` on the calling context — the smart account's master signer (or a delegated signer with sufficient weight) must authorize the call.
115
+ - The interpreter's `install` function is called **within the same transaction** as `add_context_rule` and receives the same `smart_account` address.
116
+ - **The interpreter does NOT need to read the smart account's master set** — the master signer authorizes `add_context_rule` directly; the interpreter receives the already-authorized `ContextRule` and `smart_account` address.
117
+
118
+ ### Safe mechanism for master-only install
119
+
120
+ The committed safe mechanism is **two-step install** (not out-of-band master const):
121
+ 1. Owner calls `add_context_rule` with the interpreter address + initial rule.
122
+ 2. Interpreter's `install` is called within the same auth context — the `Context` passed to `Policy::enforce` confirms the call is authorized by the smart account's current signer set.
123
+ 3. Re-install is structurally possible via `install_nonce` (stored nonce + 1 check).
124
+
125
+ ---
126
+
127
+ ## Framework Limits (OZ Hard Limits)
128
+
129
+ Source: `packages/accounts/src/smart_account/storage.rs` (permalinked above)
130
+
131
+ | Limit | Value |
132
+ |---|---|
133
+ | `maxPoliciesPerRule` | **5** |
134
+ | `maxSignersPerRule` | **15** |
135
+ | Per-account rule cap | **None** (OZ imposes no cap) |
136
+
137
+ These are enforced by OZ internally; the interpreter enforces the same caps at install time.
138
+
139
+ ---
140
+
141
+ ## add_policy (Second Attach Path)
142
+
143
+ `add_context_rule` installs the rule + signers. A **second separate call** (`add_policy`) attaches a policy contract to an existing rule:
144
+
145
+ ```rust
146
+ pub fn add_policy(
147
+ e: &Env,
148
+ context_rule_id: u32,
149
+ policy: Address,
150
+ install_param: Val,
151
+ ) -> u32
152
+ ```
153
+
154
+ Parameters:
155
+ - `context_rule_id: u32` — the rule to attach to
156
+ - `policy: Address` — the policy contract address
157
+ - `install_param: Val` — arbitrary `Val` passed to `Policy::install`; for the interpreter this is `PolicyInstallParams` as ScVal
158
+ - Returns `u32` — the new policy id within the rule
159
+
160
+ **Auth:** same pattern — `require_auth` on the smart account. The `policy` address must point to a deployed `Policy` contract.
161
+
162
+ ---
163
+
164
+ ## Related Files
165
+
166
+ | File | Purpose |
167
+ |---|---|
168
+ | `packages/accounts/src/smart_account/mod.rs` | Smart account contract entry points |
169
+ | `packages/accounts/src/smart_account/storage.rs` | Signer, ContextRule, add_context_rule, add_policy |
170
+ | `packages/accounts/src/policies/mod.rs` | Policy trait definition |
171
+ | `packages/accounts/src/policies/oz_primitive.rs` | Built-in OZ policies (spending_limit, threshold) |