@crediolabs/policy-synth 0.5.0 → 0.5.1

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.
@@ -48,6 +48,13 @@ function jsonToLeaf(value) {
48
48
  return { kind: 'call_arg', index: numberField(v, 'index') };
49
49
  case 'call_arg_len':
50
50
  return { kind: 'call_arg_len', index: numberField(v, 'index') };
51
+ case 'call_arg_field':
52
+ return {
53
+ kind: 'call_arg_field',
54
+ index: numberField(v, 'index'),
55
+ element: numberField(v, 'element'),
56
+ field: stringField(v, 'field'),
57
+ };
51
58
  case 'call_arg_scaled':
52
59
  // num/den stay decimal STRINGS: an i128 ratio does not survive a JS
53
60
  // number, and silently rounding one would change the floor.
@@ -3,8 +3,8 @@ import { type AuthorityOverlap } from '../install/authority-overlap.ts';
3
3
  import { type BuildInstallPolicyResult, type BuildRevokePolicyResult } from '../install/build-install-policy.ts';
4
4
  import { getInterpreterInfo } from '../install/get-interpreter-info.ts';
5
5
  import { type RecordTransactionInput, type SimulatePolicyInput, type SynthesizePolicyInput, type VerifyPolicyInput } from './schemas.ts';
6
- export type { DeclarePolicyInput, GetInterpreterInfoInput, InstallPolicyInput, RecordTransactionInput, RevokePolicyInput, SimulatePolicyInput, SynthesizePolicyInput, VerifyPolicyInput, } from './schemas.ts';
7
- export { ComposeUserResponsesSchema, DeclarePolicyInputSchema, GetInterpreterInfoInputSchema, InstallPolicyInputSchema, InterpreterOptionsSchema, MAINNET_RPC_URL, NetworkSchema, PINNED_INTERPRETER_ADDRESS_BY_NETWORK, PINNED_INTERPRETER_GRAMMAR_VERSION, PINNED_INTERPRETER_MAINNET_ADDRESS, PINNED_INTERPRETER_TESTNET_ADDRESS, PINNED_INTERPRETER_WASM_SHA256, PredicateLeafSchema, PredicateNodeSchema, RecordedTransactionSchema, RecordTransactionInputSchema, RevokePolicyInputSchema, RPC_URL_BY_NETWORK, SynthesizePolicyInputSchema, TESTNET_RPC_URL, ToolErrorSchema, } from './schemas.ts';
6
+ export type { DeclarePolicyInput, GetInterpreterInfoInput, InstallPolicyInput, OzBuiltinPolicy, RecordTransactionInput, RevokePolicyInput, SimulatePolicyInput, SynthesizePolicyInput, VerifyPolicyInput, } from './schemas.ts';
7
+ export { ComposeUserResponsesSchema, DeclarePolicyInputSchema, GetInterpreterInfoInputSchema, InstallPolicyInputSchema, InterpreterOptionsSchema, MAINNET_RPC_URL, NetworkSchema, PINNED_INTERPRETER_ADDRESS_BY_NETWORK, PINNED_INTERPRETER_GRAMMAR_VERSION, PINNED_INTERPRETER_MAINNET_ADDRESS, PINNED_INTERPRETER_TESTNET_ADDRESS, PINNED_INTERPRETER_WASM_SHA256, PINNED_OZ_POLICY_ADDRESS_BY_NETWORK, PINNED_OZ_POLICY_WASM_SHA256, PredicateLeafSchema, PredicateNodeSchema, RecordedTransactionSchema, RecordTransactionInputSchema, RevokePolicyInputSchema, RPC_URL_BY_NETWORK, SynthesizePolicyInputSchema, TESTNET_RPC_URL, ToolErrorSchema, } from './schemas.ts';
8
8
  export type RunRecordTransactionInput = RecordTransactionInput;
9
9
  export type RunSynthesizePolicyInput = SynthesizePolicyInput;
10
10
  export type RunSimulatePolicyInput = SimulatePolicyInput;
package/dist/run/index.js CHANGED
@@ -30,7 +30,7 @@ import { DeclarePolicyInputSchema, GetInterpreterInfoInputSchema, InstallPolicyI
30
30
  // downstream consumer) can import the canonical input shapes from the same
31
31
  // module that owns the tool-body glue. The strict schemas are the source of
32
32
  // truth - MCP tool shapes are derived from them.
33
- export { ComposeUserResponsesSchema, DeclarePolicyInputSchema, GetInterpreterInfoInputSchema, InstallPolicyInputSchema, InterpreterOptionsSchema, MAINNET_RPC_URL, NetworkSchema, PINNED_INTERPRETER_ADDRESS_BY_NETWORK, PINNED_INTERPRETER_GRAMMAR_VERSION, PINNED_INTERPRETER_MAINNET_ADDRESS, PINNED_INTERPRETER_TESTNET_ADDRESS, PINNED_INTERPRETER_WASM_SHA256, PredicateLeafSchema, PredicateNodeSchema, RecordedTransactionSchema, RecordTransactionInputSchema, RevokePolicyInputSchema, RPC_URL_BY_NETWORK, SynthesizePolicyInputSchema, TESTNET_RPC_URL, ToolErrorSchema, } from "./schemas.js";
33
+ export { ComposeUserResponsesSchema, DeclarePolicyInputSchema, GetInterpreterInfoInputSchema, InstallPolicyInputSchema, InterpreterOptionsSchema, MAINNET_RPC_URL, NetworkSchema, PINNED_INTERPRETER_ADDRESS_BY_NETWORK, PINNED_INTERPRETER_GRAMMAR_VERSION, PINNED_INTERPRETER_MAINNET_ADDRESS, PINNED_INTERPRETER_TESTNET_ADDRESS, PINNED_INTERPRETER_WASM_SHA256, PINNED_OZ_POLICY_ADDRESS_BY_NETWORK, PINNED_OZ_POLICY_WASM_SHA256, PredicateLeafSchema, PredicateNodeSchema, RecordedTransactionSchema, RecordTransactionInputSchema, RevokePolicyInputSchema, RPC_URL_BY_NETWORK, SynthesizePolicyInputSchema, TESTNET_RPC_URL, ToolErrorSchema, } from "./schemas.js";
34
34
  /** Map every tool name to its canonical domain error code. Replaces a 7-way
35
35
  * if/else so adding a tool adds one line here rather than a new branch in
36
36
  * each envelope call. */
@@ -1627,6 +1627,25 @@ export declare const MAINNET_RPC_URL = "https://mainnet.sorobanrpc.com";
1627
1627
  * a single constant - only the addresses and RPCs are network-scoped. */
1628
1628
  export declare const PINNED_INTERPRETER_ADDRESS_BY_NETWORK: Record<Network, string>;
1629
1629
  export declare const RPC_URL_BY_NETWORK: Record<Network, string>;
1630
+ /** The OpenZeppelin built-in policies we deployed instances of. These are OZ
1631
+ * EXAMPLE contracts, built by us from `OpenZeppelin/stellar-contracts` at tag
1632
+ * v0.7.2 and deployed by us. We have NOT audited them and upstream ships an
1633
+ * "experimental software ... as is" disclaimer; anything surfacing one of
1634
+ * these to a user must say so rather than implying we vouch for the code.
1635
+ * Provenance detail in `docs/audit/README.md` finding 7. */
1636
+ export type OzBuiltinPolicy = 'spending_limit' | 'simple_threshold' | 'weighted_threshold';
1637
+ /** Instance addresses per network. Exported so consumers import the pin
1638
+ * instead of copying a literal - a copied address is how a testnet id ends up
1639
+ * being queried against mainnet, which returns `Error(Storage, MissingValue)`
1640
+ * and reads exactly like "nothing is deployed there".
1641
+ *
1642
+ * Instance ids are network-scoped, so the addresses differ while the wasm
1643
+ * hash does not: each pair below was created from the same uploaded wasm (see
1644
+ * `PINNED_OZ_POLICY_WASM_SHA256`), verified by fetching the deployed bytes
1645
+ * back from both networks. */
1646
+ export declare const PINNED_OZ_POLICY_ADDRESS_BY_NETWORK: Record<Network, Record<OzBuiltinPolicy, string>>;
1647
+ /** sha256 of each deployed policy wasm, identical across both networks. */
1648
+ export declare const PINNED_OZ_POLICY_WASM_SHA256: Record<OzBuiltinPolicy, string>;
1630
1649
  /** Stellar network passphrases. Pinned here so the XDR envelope uses the
1631
1650
  * matching passphrase when the wallet signs (a mismatch yields invalid
1632
1651
  * hashes). */
@@ -364,6 +364,33 @@ export const RPC_URL_BY_NETWORK = {
364
364
  testnet: TESTNET_RPC_URL,
365
365
  mainnet: MAINNET_RPC_URL,
366
366
  };
367
+ /** Instance addresses per network. Exported so consumers import the pin
368
+ * instead of copying a literal - a copied address is how a testnet id ends up
369
+ * being queried against mainnet, which returns `Error(Storage, MissingValue)`
370
+ * and reads exactly like "nothing is deployed there".
371
+ *
372
+ * Instance ids are network-scoped, so the addresses differ while the wasm
373
+ * hash does not: each pair below was created from the same uploaded wasm (see
374
+ * `PINNED_OZ_POLICY_WASM_SHA256`), verified by fetching the deployed bytes
375
+ * back from both networks. */
376
+ export const PINNED_OZ_POLICY_ADDRESS_BY_NETWORK = {
377
+ testnet: {
378
+ spending_limit: 'CDH4KOBRUEZI6TTZ72YXR5YUIODB6RH3AF75KX56Z73DELRCA5TWFISP',
379
+ simple_threshold: 'CAYTIVQOEZDOQI4GC3XBXEEYHQUANQQJHPJVMXVRBREGSAP6TCN3DID6',
380
+ weighted_threshold: 'CCTNRFZCL45GTJICA3Z2KFQO3VEGBHGCVBLHQ3GLJKAGACQIJMYJS7T2',
381
+ },
382
+ mainnet: {
383
+ spending_limit: 'CA7IBD266HIHFDUIBZLPIAITJUA3DVY4JAG6K3QMGBKLZCXXLP5E2F7A',
384
+ simple_threshold: 'CDOGPGUFGGUDG25P3TG6XIXJKRRYOZ3PXUZIEPVH74KXRZIDKZ5HYEOS',
385
+ weighted_threshold: 'CDWPZ4YZ3YIJ64XSHRMERRF2L2H7XD6SPUZDP3KI56T7QXQCICC25V3J',
386
+ },
387
+ };
388
+ /** sha256 of each deployed policy wasm, identical across both networks. */
389
+ export const PINNED_OZ_POLICY_WASM_SHA256 = {
390
+ spending_limit: '9ce30ea1fe5c2dc5c9c49cf3462adb32e2c11d7dfadb15ef43a51ba56568de2b',
391
+ simple_threshold: '01c0be09eb6fb288cab2e878b4e890f7a38f75afab99aeb197861f44e2e2dfe6',
392
+ weighted_threshold: '78030272b06afb09d2949ab8877c9a8ae1ab9025b48f4edafd5816cc44f76eaa',
393
+ };
367
394
  /** Stellar network passphrases. Pinned here so the XDR envelope uses the
368
395
  * matching passphrase when the wallet signs (a mismatch yields invalid
369
396
  * hashes). */
@@ -51,6 +51,13 @@ function jsonToLeaf(value) {
51
51
  return { kind: 'call_arg', index: numberField(v, 'index') };
52
52
  case 'call_arg_len':
53
53
  return { kind: 'call_arg_len', index: numberField(v, 'index') };
54
+ case 'call_arg_field':
55
+ return {
56
+ kind: 'call_arg_field',
57
+ index: numberField(v, 'index'),
58
+ element: numberField(v, 'element'),
59
+ field: stringField(v, 'field'),
60
+ };
54
61
  case 'call_arg_scaled':
55
62
  // num/den stay decimal STRINGS: an i128 ratio does not survive a JS
56
63
  // number, and silently rounding one would change the floor.
@@ -3,8 +3,8 @@ import { type AuthorityOverlap } from '../install/authority-overlap.ts';
3
3
  import { type BuildInstallPolicyResult, type BuildRevokePolicyResult } from '../install/build-install-policy.ts';
4
4
  import { getInterpreterInfo } from '../install/get-interpreter-info.ts';
5
5
  import { type RecordTransactionInput, type SimulatePolicyInput, type SynthesizePolicyInput, type VerifyPolicyInput } from './schemas.ts';
6
- export type { DeclarePolicyInput, GetInterpreterInfoInput, InstallPolicyInput, RecordTransactionInput, RevokePolicyInput, SimulatePolicyInput, SynthesizePolicyInput, VerifyPolicyInput, } from './schemas.ts';
7
- export { ComposeUserResponsesSchema, DeclarePolicyInputSchema, GetInterpreterInfoInputSchema, InstallPolicyInputSchema, InterpreterOptionsSchema, MAINNET_RPC_URL, NetworkSchema, PINNED_INTERPRETER_ADDRESS_BY_NETWORK, PINNED_INTERPRETER_GRAMMAR_VERSION, PINNED_INTERPRETER_MAINNET_ADDRESS, PINNED_INTERPRETER_TESTNET_ADDRESS, PINNED_INTERPRETER_WASM_SHA256, PredicateLeafSchema, PredicateNodeSchema, RecordedTransactionSchema, RecordTransactionInputSchema, RevokePolicyInputSchema, RPC_URL_BY_NETWORK, SynthesizePolicyInputSchema, TESTNET_RPC_URL, ToolErrorSchema, } from './schemas.ts';
6
+ export type { DeclarePolicyInput, GetInterpreterInfoInput, InstallPolicyInput, OzBuiltinPolicy, RecordTransactionInput, RevokePolicyInput, SimulatePolicyInput, SynthesizePolicyInput, VerifyPolicyInput, } from './schemas.ts';
7
+ export { ComposeUserResponsesSchema, DeclarePolicyInputSchema, GetInterpreterInfoInputSchema, InstallPolicyInputSchema, InterpreterOptionsSchema, MAINNET_RPC_URL, NetworkSchema, PINNED_INTERPRETER_ADDRESS_BY_NETWORK, PINNED_INTERPRETER_GRAMMAR_VERSION, PINNED_INTERPRETER_MAINNET_ADDRESS, PINNED_INTERPRETER_TESTNET_ADDRESS, PINNED_INTERPRETER_WASM_SHA256, PINNED_OZ_POLICY_ADDRESS_BY_NETWORK, PINNED_OZ_POLICY_WASM_SHA256, PredicateLeafSchema, PredicateNodeSchema, RecordedTransactionSchema, RecordTransactionInputSchema, RevokePolicyInputSchema, RPC_URL_BY_NETWORK, SynthesizePolicyInputSchema, TESTNET_RPC_URL, ToolErrorSchema, } from './schemas.ts';
8
8
  export type RunRecordTransactionInput = RecordTransactionInput;
9
9
  export type RunSynthesizePolicyInput = SynthesizePolicyInput;
10
10
  export type RunSimulatePolicyInput = SimulatePolicyInput;
@@ -18,7 +18,7 @@
18
18
  // No business logic. No retries. No session state. The same call shape can
19
19
  // drive the CLI (which calls into the same core directly without MCP).
20
20
  Object.defineProperty(exports, "__esModule", { value: true });
21
- exports.ToolErrorSchema = exports.TESTNET_RPC_URL = exports.SynthesizePolicyInputSchema = exports.RPC_URL_BY_NETWORK = exports.RevokePolicyInputSchema = exports.RecordTransactionInputSchema = exports.RecordedTransactionSchema = exports.PredicateNodeSchema = exports.PredicateLeafSchema = exports.PINNED_INTERPRETER_WASM_SHA256 = exports.PINNED_INTERPRETER_TESTNET_ADDRESS = exports.PINNED_INTERPRETER_MAINNET_ADDRESS = exports.PINNED_INTERPRETER_GRAMMAR_VERSION = exports.PINNED_INTERPRETER_ADDRESS_BY_NETWORK = exports.NetworkSchema = exports.MAINNET_RPC_URL = exports.InterpreterOptionsSchema = exports.InstallPolicyInputSchema = exports.GetInterpreterInfoInputSchema = exports.DeclarePolicyInputSchema = exports.ComposeUserResponsesSchema = void 0;
21
+ exports.ToolErrorSchema = exports.TESTNET_RPC_URL = exports.SynthesizePolicyInputSchema = exports.RPC_URL_BY_NETWORK = exports.RevokePolicyInputSchema = exports.RecordTransactionInputSchema = exports.RecordedTransactionSchema = exports.PredicateNodeSchema = exports.PredicateLeafSchema = exports.PINNED_OZ_POLICY_WASM_SHA256 = exports.PINNED_OZ_POLICY_ADDRESS_BY_NETWORK = exports.PINNED_INTERPRETER_WASM_SHA256 = exports.PINNED_INTERPRETER_TESTNET_ADDRESS = exports.PINNED_INTERPRETER_MAINNET_ADDRESS = exports.PINNED_INTERPRETER_GRAMMAR_VERSION = exports.PINNED_INTERPRETER_ADDRESS_BY_NETWORK = exports.NetworkSchema = exports.MAINNET_RPC_URL = exports.InterpreterOptionsSchema = exports.InstallPolicyInputSchema = exports.GetInterpreterInfoInputSchema = exports.DeclarePolicyInputSchema = exports.ComposeUserResponsesSchema = void 0;
22
22
  exports.runRecordTransaction = runRecordTransaction;
23
23
  exports.runSynthesizePolicy = runSynthesizePolicy;
24
24
  exports.runInstallPolicy = runInstallPolicy;
@@ -55,6 +55,8 @@ Object.defineProperty(exports, "PINNED_INTERPRETER_GRAMMAR_VERSION", { enumerabl
55
55
  Object.defineProperty(exports, "PINNED_INTERPRETER_MAINNET_ADDRESS", { enumerable: true, get: function () { return schemas_ts_2.PINNED_INTERPRETER_MAINNET_ADDRESS; } });
56
56
  Object.defineProperty(exports, "PINNED_INTERPRETER_TESTNET_ADDRESS", { enumerable: true, get: function () { return schemas_ts_2.PINNED_INTERPRETER_TESTNET_ADDRESS; } });
57
57
  Object.defineProperty(exports, "PINNED_INTERPRETER_WASM_SHA256", { enumerable: true, get: function () { return schemas_ts_2.PINNED_INTERPRETER_WASM_SHA256; } });
58
+ Object.defineProperty(exports, "PINNED_OZ_POLICY_ADDRESS_BY_NETWORK", { enumerable: true, get: function () { return schemas_ts_2.PINNED_OZ_POLICY_ADDRESS_BY_NETWORK; } });
59
+ Object.defineProperty(exports, "PINNED_OZ_POLICY_WASM_SHA256", { enumerable: true, get: function () { return schemas_ts_2.PINNED_OZ_POLICY_WASM_SHA256; } });
58
60
  Object.defineProperty(exports, "PredicateLeafSchema", { enumerable: true, get: function () { return schemas_ts_2.PredicateLeafSchema; } });
59
61
  Object.defineProperty(exports, "PredicateNodeSchema", { enumerable: true, get: function () { return schemas_ts_2.PredicateNodeSchema; } });
60
62
  Object.defineProperty(exports, "RecordedTransactionSchema", { enumerable: true, get: function () { return schemas_ts_2.RecordedTransactionSchema; } });
@@ -1627,6 +1627,25 @@ export declare const MAINNET_RPC_URL = "https://mainnet.sorobanrpc.com";
1627
1627
  * a single constant - only the addresses and RPCs are network-scoped. */
1628
1628
  export declare const PINNED_INTERPRETER_ADDRESS_BY_NETWORK: Record<Network, string>;
1629
1629
  export declare const RPC_URL_BY_NETWORK: Record<Network, string>;
1630
+ /** The OpenZeppelin built-in policies we deployed instances of. These are OZ
1631
+ * EXAMPLE contracts, built by us from `OpenZeppelin/stellar-contracts` at tag
1632
+ * v0.7.2 and deployed by us. We have NOT audited them and upstream ships an
1633
+ * "experimental software ... as is" disclaimer; anything surfacing one of
1634
+ * these to a user must say so rather than implying we vouch for the code.
1635
+ * Provenance detail in `docs/audit/README.md` finding 7. */
1636
+ export type OzBuiltinPolicy = 'spending_limit' | 'simple_threshold' | 'weighted_threshold';
1637
+ /** Instance addresses per network. Exported so consumers import the pin
1638
+ * instead of copying a literal - a copied address is how a testnet id ends up
1639
+ * being queried against mainnet, which returns `Error(Storage, MissingValue)`
1640
+ * and reads exactly like "nothing is deployed there".
1641
+ *
1642
+ * Instance ids are network-scoped, so the addresses differ while the wasm
1643
+ * hash does not: each pair below was created from the same uploaded wasm (see
1644
+ * `PINNED_OZ_POLICY_WASM_SHA256`), verified by fetching the deployed bytes
1645
+ * back from both networks. */
1646
+ export declare const PINNED_OZ_POLICY_ADDRESS_BY_NETWORK: Record<Network, Record<OzBuiltinPolicy, string>>;
1647
+ /** sha256 of each deployed policy wasm, identical across both networks. */
1648
+ export declare const PINNED_OZ_POLICY_WASM_SHA256: Record<OzBuiltinPolicy, string>;
1630
1649
  /** Stellar network passphrases. Pinned here so the XDR envelope uses the
1631
1650
  * matching passphrase when the wallet signs (a mismatch yields invalid
1632
1651
  * hashes). */
@@ -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.GetInterpreterInfoInputSchema = exports.RevokePolicyInputSchema = exports.InstallPolicyInputSchema = exports.DeclarePolicyInputSchema = exports.NETWORK_PASSPHRASES = exports.RPC_URL_BY_NETWORK = exports.PINNED_INTERPRETER_ADDRESS_BY_NETWORK = exports.MAINNET_RPC_URL = exports.TESTNET_RPC_URL = exports.PINNED_INTERPRETER_GRAMMAR_VERSION = exports.PINNED_INTERPRETER_WASM_SHA256 = exports.PINNED_INTERPRETER_MAINNET_ADDRESS = exports.PINNED_INTERPRETER_TESTNET_ADDRESS = exports.ObservedRuleSchema = exports.VerifyPolicyInputSchema = exports.SimulatePolicyInputSchema = exports.PredicateNodeSchema = exports.PredicateLeafSchema = exports.SynthesizePolicyInputSchema = exports.InterpreterOptionsSchema = exports.RecordTransactionInputSchema = exports.ComposeUserResponsesSchema = 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.DeclarePolicyInputSchema = exports.NETWORK_PASSPHRASES = exports.PINNED_OZ_POLICY_WASM_SHA256 = exports.PINNED_OZ_POLICY_ADDRESS_BY_NETWORK = exports.RPC_URL_BY_NETWORK = exports.PINNED_INTERPRETER_ADDRESS_BY_NETWORK = exports.MAINNET_RPC_URL = exports.TESTNET_RPC_URL = exports.PINNED_INTERPRETER_GRAMMAR_VERSION = exports.PINNED_INTERPRETER_WASM_SHA256 = exports.PINNED_INTERPRETER_MAINNET_ADDRESS = exports.PINNED_INTERPRETER_TESTNET_ADDRESS = exports.ObservedRuleSchema = exports.VerifyPolicyInputSchema = exports.SimulatePolicyInputSchema = exports.PredicateNodeSchema = exports.PredicateLeafSchema = exports.SynthesizePolicyInputSchema = exports.InterpreterOptionsSchema = exports.RecordTransactionInputSchema = exports.ComposeUserResponsesSchema = 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
@@ -367,6 +367,33 @@ exports.RPC_URL_BY_NETWORK = {
367
367
  testnet: exports.TESTNET_RPC_URL,
368
368
  mainnet: exports.MAINNET_RPC_URL,
369
369
  };
370
+ /** Instance addresses per network. Exported so consumers import the pin
371
+ * instead of copying a literal - a copied address is how a testnet id ends up
372
+ * being queried against mainnet, which returns `Error(Storage, MissingValue)`
373
+ * and reads exactly like "nothing is deployed there".
374
+ *
375
+ * Instance ids are network-scoped, so the addresses differ while the wasm
376
+ * hash does not: each pair below was created from the same uploaded wasm (see
377
+ * `PINNED_OZ_POLICY_WASM_SHA256`), verified by fetching the deployed bytes
378
+ * back from both networks. */
379
+ exports.PINNED_OZ_POLICY_ADDRESS_BY_NETWORK = {
380
+ testnet: {
381
+ spending_limit: 'CDH4KOBRUEZI6TTZ72YXR5YUIODB6RH3AF75KX56Z73DELRCA5TWFISP',
382
+ simple_threshold: 'CAYTIVQOEZDOQI4GC3XBXEEYHQUANQQJHPJVMXVRBREGSAP6TCN3DID6',
383
+ weighted_threshold: 'CCTNRFZCL45GTJICA3Z2KFQO3VEGBHGCVBLHQ3GLJKAGACQIJMYJS7T2',
384
+ },
385
+ mainnet: {
386
+ spending_limit: 'CA7IBD266HIHFDUIBZLPIAITJUA3DVY4JAG6K3QMGBKLZCXXLP5E2F7A',
387
+ simple_threshold: 'CDOGPGUFGGUDG25P3TG6XIXJKRRYOZ3PXUZIEPVH74KXRZIDKZ5HYEOS',
388
+ weighted_threshold: 'CDWPZ4YZ3YIJ64XSHRMERRF2L2H7XD6SPUZDP3KI56T7QXQCICC25V3J',
389
+ },
390
+ };
391
+ /** sha256 of each deployed policy wasm, identical across both networks. */
392
+ exports.PINNED_OZ_POLICY_WASM_SHA256 = {
393
+ spending_limit: '9ce30ea1fe5c2dc5c9c49cf3462adb32e2c11d7dfadb15ef43a51ba56568de2b',
394
+ simple_threshold: '01c0be09eb6fb288cab2e878b4e890f7a38f75afab99aeb197861f44e2e2dfe6',
395
+ weighted_threshold: '78030272b06afb09d2949ab8877c9a8ae1ab9025b48f4edafd5816cc44f76eaa',
396
+ };
370
397
  /** Stellar network passphrases. Pinned here so the XDR envelope uses the
371
398
  * matching passphrase when the wallet signs (a mismatch yields invalid
372
399
  * hashes). */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crediolabs/policy-synth",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
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",
@@ -57,6 +57,13 @@ function jsonToLeaf(value: unknown): PredicateLeaf {
57
57
  return { kind: 'call_arg', index: numberField(v, 'index') }
58
58
  case 'call_arg_len':
59
59
  return { kind: 'call_arg_len', index: numberField(v, 'index') }
60
+ case 'call_arg_field':
61
+ return {
62
+ kind: 'call_arg_field',
63
+ index: numberField(v, 'index'),
64
+ element: numberField(v, 'element'),
65
+ field: stringField(v, 'field'),
66
+ }
60
67
  case 'call_arg_scaled':
61
68
  // num/den stay decimal STRINGS: an i128 ratio does not survive a JS
62
69
  // number, and silently rounding one would change the floor.
package/src/run/index.ts CHANGED
@@ -77,6 +77,7 @@ export type {
77
77
  DeclarePolicyInput,
78
78
  GetInterpreterInfoInput,
79
79
  InstallPolicyInput,
80
+ OzBuiltinPolicy,
80
81
  RecordTransactionInput,
81
82
  RevokePolicyInput,
82
83
  SimulatePolicyInput,
@@ -100,6 +101,8 @@ export {
100
101
  PINNED_INTERPRETER_MAINNET_ADDRESS,
101
102
  PINNED_INTERPRETER_TESTNET_ADDRESS,
102
103
  PINNED_INTERPRETER_WASM_SHA256,
104
+ PINNED_OZ_POLICY_ADDRESS_BY_NETWORK,
105
+ PINNED_OZ_POLICY_WASM_SHA256,
103
106
  PredicateLeafSchema,
104
107
  PredicateNodeSchema,
105
108
  RecordedTransactionSchema,
@@ -421,6 +421,46 @@ export const RPC_URL_BY_NETWORK: Record<Network, string> = {
421
421
  mainnet: MAINNET_RPC_URL,
422
422
  }
423
423
 
424
+ /** The OpenZeppelin built-in policies we deployed instances of. These are OZ
425
+ * EXAMPLE contracts, built by us from `OpenZeppelin/stellar-contracts` at tag
426
+ * v0.7.2 and deployed by us. We have NOT audited them and upstream ships an
427
+ * "experimental software ... as is" disclaimer; anything surfacing one of
428
+ * these to a user must say so rather than implying we vouch for the code.
429
+ * Provenance detail in `docs/audit/README.md` finding 7. */
430
+ export type OzBuiltinPolicy = 'spending_limit' | 'simple_threshold' | 'weighted_threshold'
431
+
432
+ /** Instance addresses per network. Exported so consumers import the pin
433
+ * instead of copying a literal - a copied address is how a testnet id ends up
434
+ * being queried against mainnet, which returns `Error(Storage, MissingValue)`
435
+ * and reads exactly like "nothing is deployed there".
436
+ *
437
+ * Instance ids are network-scoped, so the addresses differ while the wasm
438
+ * hash does not: each pair below was created from the same uploaded wasm (see
439
+ * `PINNED_OZ_POLICY_WASM_SHA256`), verified by fetching the deployed bytes
440
+ * back from both networks. */
441
+ export const PINNED_OZ_POLICY_ADDRESS_BY_NETWORK: Record<
442
+ Network,
443
+ Record<OzBuiltinPolicy, string>
444
+ > = {
445
+ testnet: {
446
+ spending_limit: 'CDH4KOBRUEZI6TTZ72YXR5YUIODB6RH3AF75KX56Z73DELRCA5TWFISP',
447
+ simple_threshold: 'CAYTIVQOEZDOQI4GC3XBXEEYHQUANQQJHPJVMXVRBREGSAP6TCN3DID6',
448
+ weighted_threshold: 'CCTNRFZCL45GTJICA3Z2KFQO3VEGBHGCVBLHQ3GLJKAGACQIJMYJS7T2',
449
+ },
450
+ mainnet: {
451
+ spending_limit: 'CA7IBD266HIHFDUIBZLPIAITJUA3DVY4JAG6K3QMGBKLZCXXLP5E2F7A',
452
+ simple_threshold: 'CDOGPGUFGGUDG25P3TG6XIXJKRRYOZ3PXUZIEPVH74KXRZIDKZ5HYEOS',
453
+ weighted_threshold: 'CDWPZ4YZ3YIJ64XSHRMERRF2L2H7XD6SPUZDP3KI56T7QXQCICC25V3J',
454
+ },
455
+ }
456
+
457
+ /** sha256 of each deployed policy wasm, identical across both networks. */
458
+ export const PINNED_OZ_POLICY_WASM_SHA256: Record<OzBuiltinPolicy, string> = {
459
+ spending_limit: '9ce30ea1fe5c2dc5c9c49cf3462adb32e2c11d7dfadb15ef43a51ba56568de2b',
460
+ simple_threshold: '01c0be09eb6fb288cab2e878b4e890f7a38f75afab99aeb197861f44e2e2dfe6',
461
+ weighted_threshold: '78030272b06afb09d2949ab8877c9a8ae1ab9025b48f4edafd5816cc44f76eaa',
462
+ }
463
+
424
464
  /** Stellar network passphrases. Pinned here so the XDR envelope uses the
425
465
  * matching passphrase when the wallet signs (a mismatch yields invalid
426
466
  * hashes). */