@crediolabs/policy-synth 0.5.1 → 0.5.2

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.
@@ -18,7 +18,7 @@
18
18
  // rather than by tooling - which is why the tooling now exists.
19
19
  //
20
20
  // Adapted to grammar 3 from the version published in `@crediolabs/policy-synth`
21
- // 0.2.0, which came from the `octogate` repository and was lost when the npm
21
+ // 0.2.0, which came from a different repository and was lost when the npm
22
22
  // lineage moved here. `or` and `not` are gone from the grammar, so the cases
23
23
  // handling them are gone too; oracle bounds are gone from the stored document.
24
24
  //
@@ -121,12 +121,23 @@ function encodeSigner(s) {
121
121
  function encodePoliciesMap(args) {
122
122
  const entries = [];
123
123
  for (const ref of args.policies) {
124
- if (ref.kind === 'interpreter') {
125
- entries.push(new xdr.ScMapEntry({
126
- key: Address.fromString(ref.interpreterAddress).toScVal(),
127
- val: encodePolicyInstallParams(args),
128
- }));
124
+ // Refuse anything that is not an interpreter policy rather than skipping
125
+ // it. This loop used to `if (kind === 'interpreter')` and drop everything
126
+ // else in silence, so a caller attaching an OZ `spending_limit` beside the
127
+ // interpreter got a rule WITHOUT the cap and no indication of it - the
128
+ // policy the user asked for was simply absent from the install they signed.
129
+ // `PolicyRef` has one shape today, so TypeScript narrows this branch to
130
+ // `never`; the guard is for callers reaching the built JS untyped, and for
131
+ // the next kind added to `PolicyRef` without a case here. Failing loudly is
132
+ // the only safe direction: a dropped policy is a missing restriction.
133
+ if (ref.kind !== 'interpreter') {
134
+ const kind = JSON.stringify(ref.kind ?? null);
135
+ throw limitError('INSTALL_BUILD_FAILED', `policy kind ${kind} is not supported; this builder attaches interpreter policies only. Attach an OpenZeppelin built-in through the account layer instead - dropping it here would install a rule missing the restriction you asked for.`);
129
136
  }
137
+ entries.push(new xdr.ScMapEntry({
138
+ key: Address.fromString(ref.interpreterAddress).toScVal(),
139
+ val: encodePolicyInstallParams(args),
140
+ }));
130
141
  }
131
142
  entries.sort(sortByScValSymbolString);
132
143
  return xdr.ScVal.scvMap(entries);
@@ -19,7 +19,7 @@
19
19
  // rather than by tooling - which is why the tooling now exists.
20
20
  //
21
21
  // Adapted to grammar 3 from the version published in `@crediolabs/policy-synth`
22
- // 0.2.0, which came from the `octogate` repository and was lost when the npm
22
+ // 0.2.0, which came from a different repository and was lost when the npm
23
23
  // lineage moved here. `or` and `not` are gone from the grammar, so the cases
24
24
  // handling them are gone too; oracle bounds are gone from the stored document.
25
25
  //
@@ -125,12 +125,23 @@ function encodeSigner(s) {
125
125
  function encodePoliciesMap(args) {
126
126
  const entries = [];
127
127
  for (const ref of args.policies) {
128
- if (ref.kind === 'interpreter') {
129
- entries.push(new stellar_sdk_1.xdr.ScMapEntry({
130
- key: stellar_sdk_1.Address.fromString(ref.interpreterAddress).toScVal(),
131
- val: encodePolicyInstallParams(args),
132
- }));
128
+ // Refuse anything that is not an interpreter policy rather than skipping
129
+ // it. This loop used to `if (kind === 'interpreter')` and drop everything
130
+ // else in silence, so a caller attaching an OZ `spending_limit` beside the
131
+ // interpreter got a rule WITHOUT the cap and no indication of it - the
132
+ // policy the user asked for was simply absent from the install they signed.
133
+ // `PolicyRef` has one shape today, so TypeScript narrows this branch to
134
+ // `never`; the guard is for callers reaching the built JS untyped, and for
135
+ // the next kind added to `PolicyRef` without a case here. Failing loudly is
136
+ // the only safe direction: a dropped policy is a missing restriction.
137
+ if (ref.kind !== 'interpreter') {
138
+ const kind = JSON.stringify(ref.kind ?? null);
139
+ throw limitError('INSTALL_BUILD_FAILED', `policy kind ${kind} is not supported; this builder attaches interpreter policies only. Attach an OpenZeppelin built-in through the account layer instead - dropping it here would install a rule missing the restriction you asked for.`);
133
140
  }
141
+ entries.push(new stellar_sdk_1.xdr.ScMapEntry({
142
+ key: stellar_sdk_1.Address.fromString(ref.interpreterAddress).toScVal(),
143
+ val: encodePolicyInstallParams(args),
144
+ }));
134
145
  }
135
146
  entries.sort(sortByScValSymbolString);
136
147
  return stellar_sdk_1.xdr.ScVal.scvMap(entries);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crediolabs/policy-synth",
3
- "version": "0.5.1",
3
+ "version": "0.5.2",
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",
@@ -18,7 +18,7 @@
18
18
  // rather than by tooling - which is why the tooling now exists.
19
19
  //
20
20
  // Adapted to grammar 3 from the version published in `@crediolabs/policy-synth`
21
- // 0.2.0, which came from the `octogate` repository and was lost when the npm
21
+ // 0.2.0, which came from a different repository and was lost when the npm
22
22
  // lineage moved here. `or` and `not` are gone from the grammar, so the cases
23
23
  // handling them are gone too; oracle bounds are gone from the stored document.
24
24
  //
@@ -194,14 +194,28 @@ function encodeSigner(s: SignerDraft): xdr.ScVal {
194
194
  function encodePoliciesMap(args: BuildAddContextRuleArgs): xdr.ScVal {
195
195
  const entries: xdr.ScMapEntry[] = []
196
196
  for (const ref of args.policies) {
197
- if (ref.kind === 'interpreter') {
198
- entries.push(
199
- new xdr.ScMapEntry({
200
- key: Address.fromString(ref.interpreterAddress).toScVal(),
201
- val: encodePolicyInstallParams(args),
202
- })
197
+ // Refuse anything that is not an interpreter policy rather than skipping
198
+ // it. This loop used to `if (kind === 'interpreter')` and drop everything
199
+ // else in silence, so a caller attaching an OZ `spending_limit` beside the
200
+ // interpreter got a rule WITHOUT the cap and no indication of it - the
201
+ // policy the user asked for was simply absent from the install they signed.
202
+ // `PolicyRef` has one shape today, so TypeScript narrows this branch to
203
+ // `never`; the guard is for callers reaching the built JS untyped, and for
204
+ // the next kind added to `PolicyRef` without a case here. Failing loudly is
205
+ // the only safe direction: a dropped policy is a missing restriction.
206
+ if (ref.kind !== 'interpreter') {
207
+ const kind = JSON.stringify((ref as { kind?: unknown }).kind ?? null)
208
+ throw limitError(
209
+ 'INSTALL_BUILD_FAILED',
210
+ `policy kind ${kind} is not supported; this builder attaches interpreter policies only. Attach an OpenZeppelin built-in through the account layer instead - dropping it here would install a rule missing the restriction you asked for.`
203
211
  )
204
212
  }
213
+ entries.push(
214
+ new xdr.ScMapEntry({
215
+ key: Address.fromString(ref.interpreterAddress).toScVal(),
216
+ val: encodePolicyInstallParams(args),
217
+ })
218
+ )
205
219
  }
206
220
  entries.sort(sortByScValSymbolString)
207
221
  return xdr.ScVal.scvMap(entries)