@crediolabs/policy-synth 0.1.14 → 0.1.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/install/build-install-policy.d.ts +10 -12
- package/dist/install/build-install-policy.js +6 -10
- package/dist/install/build-install-predicate.d.ts +96 -0
- package/dist/install/build-install-predicate.js +444 -0
- package/dist/run/index.d.ts +21 -10
- package/dist/run/index.js +59 -63
- package/dist/run/schemas.d.ts +49 -8
- package/dist/run/schemas.js +47 -8
- package/dist-cjs/install/build-install-policy.d.ts +10 -12
- package/dist-cjs/install/build-install-policy.js +6 -10
- package/dist-cjs/install/build-install-predicate.d.ts +96 -0
- package/dist-cjs/install/build-install-predicate.js +479 -0
- package/dist-cjs/run/index.d.ts +21 -10
- package/dist-cjs/run/index.js +63 -62
- package/dist-cjs/run/schemas.d.ts +49 -8
- package/dist-cjs/run/schemas.js +48 -9
- package/package.json +1 -1
- package/src/install/build-install-policy.ts +16 -24
- package/src/run/index.ts +72 -72
- package/src/run/schemas.ts +51 -8
package/dist-cjs/run/index.js
CHANGED
|
@@ -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.VerifyPolicyInputSchema = exports.ToolErrorSchema = exports.SynthesizePolicyInputSchema = exports.SimulatePolicyInputSchema = exports.RevokePolicyInputSchema = exports.RecordTransactionInputSchema = exports.RecordedTransactionSchema = exports.PredicateNodeSchema = exports.PredicateLeafSchema = exports.PINNED_INTERPRETER_WASM_SHA256 = exports.PINNED_INTERPRETER_TESTNET_ADDRESS = exports.PINNED_INTERPRETER_GRAMMAR_VERSION = exports.OzAdapterConfigSchema = exports.OraclePriceFixtureSchema = exports.NetworkSchema = exports.MandateSpecSchema = exports.InterpreterOptionsSchema = exports.InstallPolicyInputSchema = exports.GetInterpreterInfoInputSchema = exports.ComposeUserResponsesSchema = void 0;
|
|
21
|
+
exports.VerifyPolicyInputSchema = exports.ToolErrorSchema = exports.TESTNET_RPC_URL = exports.SynthesizePolicyInputSchema = exports.SimulatePolicyInputSchema = 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.OzAdapterConfigSchema = exports.OraclePriceFixtureSchema = exports.NetworkSchema = exports.MandateSpecSchema = exports.MAINNET_RPC_URL = exports.InterpreterOptionsSchema = exports.InstallPolicyInputSchema = exports.GetInterpreterInfoInputSchema = exports.ComposeUserResponsesSchema = void 0;
|
|
22
22
|
exports.runRecordTransaction = runRecordTransaction;
|
|
23
23
|
exports.runSynthesizePolicy = runSynthesizePolicy;
|
|
24
24
|
exports.runSimulatePolicy = runSimulatePolicy;
|
|
@@ -43,11 +43,14 @@ Object.defineProperty(exports, "ComposeUserResponsesSchema", { enumerable: true,
|
|
|
43
43
|
Object.defineProperty(exports, "GetInterpreterInfoInputSchema", { enumerable: true, get: function () { return schemas_ts_2.GetInterpreterInfoInputSchema; } });
|
|
44
44
|
Object.defineProperty(exports, "InstallPolicyInputSchema", { enumerable: true, get: function () { return schemas_ts_2.InstallPolicyInputSchema; } });
|
|
45
45
|
Object.defineProperty(exports, "InterpreterOptionsSchema", { enumerable: true, get: function () { return schemas_ts_2.InterpreterOptionsSchema; } });
|
|
46
|
+
Object.defineProperty(exports, "MAINNET_RPC_URL", { enumerable: true, get: function () { return schemas_ts_2.MAINNET_RPC_URL; } });
|
|
46
47
|
Object.defineProperty(exports, "MandateSpecSchema", { enumerable: true, get: function () { return schemas_ts_2.MandateSpecSchema; } });
|
|
47
48
|
Object.defineProperty(exports, "NetworkSchema", { enumerable: true, get: function () { return schemas_ts_2.NetworkSchema; } });
|
|
48
49
|
Object.defineProperty(exports, "OraclePriceFixtureSchema", { enumerable: true, get: function () { return schemas_ts_2.OraclePriceFixtureSchema; } });
|
|
49
50
|
Object.defineProperty(exports, "OzAdapterConfigSchema", { enumerable: true, get: function () { return schemas_ts_2.OzAdapterConfigSchema; } });
|
|
51
|
+
Object.defineProperty(exports, "PINNED_INTERPRETER_ADDRESS_BY_NETWORK", { enumerable: true, get: function () { return schemas_ts_2.PINNED_INTERPRETER_ADDRESS_BY_NETWORK; } });
|
|
50
52
|
Object.defineProperty(exports, "PINNED_INTERPRETER_GRAMMAR_VERSION", { enumerable: true, get: function () { return schemas_ts_2.PINNED_INTERPRETER_GRAMMAR_VERSION; } });
|
|
53
|
+
Object.defineProperty(exports, "PINNED_INTERPRETER_MAINNET_ADDRESS", { enumerable: true, get: function () { return schemas_ts_2.PINNED_INTERPRETER_MAINNET_ADDRESS; } });
|
|
51
54
|
Object.defineProperty(exports, "PINNED_INTERPRETER_TESTNET_ADDRESS", { enumerable: true, get: function () { return schemas_ts_2.PINNED_INTERPRETER_TESTNET_ADDRESS; } });
|
|
52
55
|
Object.defineProperty(exports, "PINNED_INTERPRETER_WASM_SHA256", { enumerable: true, get: function () { return schemas_ts_2.PINNED_INTERPRETER_WASM_SHA256; } });
|
|
53
56
|
Object.defineProperty(exports, "PredicateLeafSchema", { enumerable: true, get: function () { return schemas_ts_2.PredicateLeafSchema; } });
|
|
@@ -55,8 +58,10 @@ Object.defineProperty(exports, "PredicateNodeSchema", { enumerable: true, get: f
|
|
|
55
58
|
Object.defineProperty(exports, "RecordedTransactionSchema", { enumerable: true, get: function () { return schemas_ts_2.RecordedTransactionSchema; } });
|
|
56
59
|
Object.defineProperty(exports, "RecordTransactionInputSchema", { enumerable: true, get: function () { return schemas_ts_2.RecordTransactionInputSchema; } });
|
|
57
60
|
Object.defineProperty(exports, "RevokePolicyInputSchema", { enumerable: true, get: function () { return schemas_ts_2.RevokePolicyInputSchema; } });
|
|
61
|
+
Object.defineProperty(exports, "RPC_URL_BY_NETWORK", { enumerable: true, get: function () { return schemas_ts_2.RPC_URL_BY_NETWORK; } });
|
|
58
62
|
Object.defineProperty(exports, "SimulatePolicyInputSchema", { enumerable: true, get: function () { return schemas_ts_2.SimulatePolicyInputSchema; } });
|
|
59
63
|
Object.defineProperty(exports, "SynthesizePolicyInputSchema", { enumerable: true, get: function () { return schemas_ts_2.SynthesizePolicyInputSchema; } });
|
|
64
|
+
Object.defineProperty(exports, "TESTNET_RPC_URL", { enumerable: true, get: function () { return schemas_ts_2.TESTNET_RPC_URL; } });
|
|
60
65
|
Object.defineProperty(exports, "ToolErrorSchema", { enumerable: true, get: function () { return schemas_ts_2.ToolErrorSchema; } });
|
|
61
66
|
Object.defineProperty(exports, "VerifyPolicyInputSchema", { enumerable: true, get: function () { return schemas_ts_2.VerifyPolicyInputSchema; } });
|
|
62
67
|
/** `record_transaction` body - wraps `recordTransaction`. The tool input
|
|
@@ -225,15 +230,17 @@ async function runVerifyPolicy(raw) {
|
|
|
225
230
|
* Returns the unsigned Soroban transaction envelope (base64 XDR) the
|
|
226
231
|
* wallet signs. The wallet signature IS the user-confirmation step - no
|
|
227
232
|
* `action_id` two-call pair (the server is stateless, see server.ts:10-12).
|
|
228
|
-
*
|
|
229
|
-
*
|
|
230
|
-
*
|
|
233
|
+
* One call installs the policy outright: `add_context_rule` carries the
|
|
234
|
+
* predicate to the interpreter in its `policies` install_param, so no
|
|
235
|
+
* separate `interpreter.install` call is needed or possible.
|
|
231
236
|
*
|
|
232
237
|
* Default-deny: an interpreter policy address other than the pinned
|
|
233
|
-
*
|
|
234
|
-
* an interpreter the caller controls); the same
|
|
235
|
-
* RPC URL (the auth nonce the wallet signs
|
|
236
|
-
* gates accept an explicit opt-in flag.
|
|
238
|
+
* interpreter for the selected network is REFUSED (the smart account
|
|
239
|
+
* would delegate to an interpreter the caller controls); the same
|
|
240
|
+
* applies to a non-pinned RPC URL (the auth nonce the wallet signs
|
|
241
|
+
* comes from the RPC). Both gates accept an explicit opt-in flag.
|
|
242
|
+
* Pin selection follows `input.network` (defaults to `testnet` so the
|
|
243
|
+
* pre-mainnet callers keep working unchanged). */
|
|
237
244
|
async function runInstallPolicy(raw) {
|
|
238
245
|
const parsed = schemas_ts_1.InstallPolicyInputSchema.safeParse(raw);
|
|
239
246
|
if (!parsed.success) {
|
|
@@ -243,17 +250,20 @@ async function runInstallPolicy(raw) {
|
|
|
243
250
|
};
|
|
244
251
|
}
|
|
245
252
|
const input = parsed.data;
|
|
253
|
+
const network = input.network ?? 'testnet';
|
|
246
254
|
// ---- Pinning gates (default-deny) ----
|
|
247
|
-
const
|
|
255
|
+
const expectedInterpreter = schemas_ts_1.PINNED_INTERPRETER_ADDRESS_BY_NETWORK[network];
|
|
256
|
+
const expectedRpc = schemas_ts_1.RPC_URL_BY_NETWORK[network];
|
|
257
|
+
const pinningError = enforceInterpreterPin(input.rule.policies, input.allowUnpinnedInterpreter, expectedInterpreter);
|
|
248
258
|
if (pinningError) {
|
|
249
259
|
return { ok: false, error: pinningError };
|
|
250
260
|
}
|
|
251
|
-
if (input.rpcUrl && input.rpcUrl !==
|
|
261
|
+
if (input.rpcUrl && input.rpcUrl !== expectedRpc && input.allowUnpinnedRpcUrl !== true) {
|
|
252
262
|
return {
|
|
253
263
|
ok: false,
|
|
254
264
|
error: {
|
|
255
265
|
code: 'INSTALL_BUILD_FAILED',
|
|
256
|
-
message: `install_policy: rpcUrl must equal the pinned
|
|
266
|
+
message: `install_policy: rpcUrl must equal the pinned ${expectedRpc} (${network}); set allowUnpinnedRpcUrl: true to opt in to a custom endpoint`,
|
|
257
267
|
severity: 'error',
|
|
258
268
|
retryable: false,
|
|
259
269
|
remediation: { toolCall: { name: 'install_policy', args: {} } },
|
|
@@ -262,7 +272,7 @@ async function runInstallPolicy(raw) {
|
|
|
262
272
|
}
|
|
263
273
|
let rpcClient;
|
|
264
274
|
try {
|
|
265
|
-
rpcClient = buildRpcClientFromInput(input.rpcUrl);
|
|
275
|
+
rpcClient = buildRpcClientFromInput(input.rpcUrl, network);
|
|
266
276
|
}
|
|
267
277
|
catch (e) {
|
|
268
278
|
return {
|
|
@@ -279,7 +289,7 @@ async function runInstallPolicy(raw) {
|
|
|
279
289
|
const result = await (0, build_install_policy_ts_1.buildInstallPolicyXdr)({
|
|
280
290
|
smartAccount: input.smartAccount,
|
|
281
291
|
sourceAccount: input.sourceAccount,
|
|
282
|
-
networkPassphrase: schemas_ts_1.NETWORK_PASSPHRASES
|
|
292
|
+
networkPassphrase: schemas_ts_1.NETWORK_PASSPHRASES[network],
|
|
283
293
|
rule: input.rule,
|
|
284
294
|
installNonce: input.installNonce,
|
|
285
295
|
encodedPredicate,
|
|
@@ -303,7 +313,8 @@ async function runInstallPolicy(raw) {
|
|
|
303
313
|
*
|
|
304
314
|
* Same RPC pin as install: a non-pinned `rpcUrl` is refused unless
|
|
305
315
|
* `allowUnpinnedRpcUrl: true`. Revoke does not carry an interpreter
|
|
306
|
-
* policy payload, so the interpreter pin is not re-checked here.
|
|
316
|
+
* policy payload, so the interpreter pin is not re-checked here.
|
|
317
|
+
* Pin selection follows `input.network` (defaults to `testnet`). */
|
|
307
318
|
async function runRevokePolicy(raw) {
|
|
308
319
|
const parsed = schemas_ts_1.RevokePolicyInputSchema.safeParse(raw);
|
|
309
320
|
if (!parsed.success) {
|
|
@@ -313,12 +324,14 @@ async function runRevokePolicy(raw) {
|
|
|
313
324
|
};
|
|
314
325
|
}
|
|
315
326
|
const input = parsed.data;
|
|
316
|
-
|
|
327
|
+
const network = input.network ?? 'testnet';
|
|
328
|
+
const expectedRpc = schemas_ts_1.RPC_URL_BY_NETWORK[network];
|
|
329
|
+
if (input.rpcUrl && input.rpcUrl !== expectedRpc && input.allowUnpinnedRpcUrl !== true) {
|
|
317
330
|
return {
|
|
318
331
|
ok: false,
|
|
319
332
|
error: {
|
|
320
333
|
code: 'REVOKE_BUILD_FAILED',
|
|
321
|
-
message: `revoke_policy: rpcUrl must equal the pinned
|
|
334
|
+
message: `revoke_policy: rpcUrl must equal the pinned ${expectedRpc} (${network}); set allowUnpinnedRpcUrl: true to opt in to a custom endpoint`,
|
|
322
335
|
severity: 'error',
|
|
323
336
|
retryable: false,
|
|
324
337
|
remediation: { toolCall: { name: 'revoke_policy', args: {} } },
|
|
@@ -327,7 +340,7 @@ async function runRevokePolicy(raw) {
|
|
|
327
340
|
}
|
|
328
341
|
let rpcClient;
|
|
329
342
|
try {
|
|
330
|
-
rpcClient = buildRpcClientFromInput(input.rpcUrl);
|
|
343
|
+
rpcClient = buildRpcClientFromInput(input.rpcUrl, network);
|
|
331
344
|
}
|
|
332
345
|
catch (e) {
|
|
333
346
|
return {
|
|
@@ -340,7 +353,7 @@ async function runRevokePolicy(raw) {
|
|
|
340
353
|
smartAccount: input.smartAccount,
|
|
341
354
|
sourceAccount: input.sourceAccount,
|
|
342
355
|
ruleId: input.ruleId,
|
|
343
|
-
networkPassphrase: schemas_ts_1.NETWORK_PASSPHRASES
|
|
356
|
+
networkPassphrase: schemas_ts_1.NETWORK_PASSPHRASES[network],
|
|
344
357
|
rpc: rpcClient,
|
|
345
358
|
...(input.baseFee !== undefined ? { baseFee: input.baseFee } : {}),
|
|
346
359
|
});
|
|
@@ -358,7 +371,15 @@ async function runRevokePolicy(raw) {
|
|
|
358
371
|
* `grammar_version()` comparison. The audit field is deliberately
|
|
359
372
|
* OMITTED (phase-04's "audit #44" has no source of truth in the repo -
|
|
360
373
|
* fabricating it would be a lie on a security surface; the live
|
|
361
|
-
* mismatch check is worth MORE).
|
|
374
|
+
* mismatch check is worth MORE).
|
|
375
|
+
*
|
|
376
|
+
* Network-aware: `input.network` selects which interpreter pin and RPC
|
|
377
|
+
* to use. Mainnet was rolled out 2026-08-04 - the same wasm hash was
|
|
378
|
+
* uploaded to mainnet as was exercised on testnet, so a single
|
|
379
|
+
* `PINNED_INTERPRETER_WASM_SHA256` constant backs both networks
|
|
380
|
+
* (DEPLOYMENTS.md:25-27). The address differs because instance ids are
|
|
381
|
+
* network-scoped. UNAUDITED at the time of writing - see
|
|
382
|
+
* DEPLOYMENTS.md:29-32 for what is still pending. */
|
|
362
383
|
async function runGetInterpreterInfo(raw) {
|
|
363
384
|
const parsed = schemas_ts_1.GetInterpreterInfoInputSchema.safeParse(raw);
|
|
364
385
|
if (!parsed.success) {
|
|
@@ -369,34 +390,15 @@ async function runGetInterpreterInfo(raw) {
|
|
|
369
390
|
}
|
|
370
391
|
const input = parsed.data;
|
|
371
392
|
const network = input.network ?? 'testnet';
|
|
372
|
-
|
|
373
|
-
// 'mainnet'` stamped on it. DEPLOYMENTS.md:3 says plainly "Testnet only.
|
|
374
|
-
// Nothing is deployed to mainnet yet", so that answer described a contract
|
|
375
|
-
// that does not exist at an address that is not on that network. This tool
|
|
376
|
-
// exists to tell a caller what they are installing against; inventing a
|
|
377
|
-
// mainnet deployment is the same failure as inventing an audit reference.
|
|
378
|
-
if (network === 'mainnet') {
|
|
379
|
-
return {
|
|
380
|
-
ok: false,
|
|
381
|
-
error: {
|
|
382
|
-
code: 'RECORDING_FAILED',
|
|
383
|
-
message: 'get_interpreter_info: no interpreter is deployed to mainnet. The pinned address and wasm hash are testnet-only; mainnet deployment is gated on the interpreter audit.',
|
|
384
|
-
severity: 'error',
|
|
385
|
-
retryable: false,
|
|
386
|
-
remediation: {
|
|
387
|
-
toolCall: { name: 'get_interpreter_info', args: { network: 'testnet' } },
|
|
388
|
-
},
|
|
389
|
-
},
|
|
390
|
-
};
|
|
391
|
-
}
|
|
393
|
+
const pinnedAddress = schemas_ts_1.PINNED_INTERPRETER_ADDRESS_BY_NETWORK[network];
|
|
392
394
|
try {
|
|
393
395
|
let deployedGrammarVersion;
|
|
394
396
|
if (input.verifyLive === true) {
|
|
395
|
-
const rpcClient = buildRpcClientFromInput(input.rpcUrl);
|
|
396
|
-
deployedGrammarVersion = await rpcClient.getContractVersion(
|
|
397
|
+
const rpcClient = buildRpcClientFromInput(input.rpcUrl, network);
|
|
398
|
+
deployedGrammarVersion = await rpcClient.getContractVersion(pinnedAddress);
|
|
397
399
|
}
|
|
398
400
|
const info = (0, get_interpreter_info_ts_1.getInterpreterInfo)({
|
|
399
|
-
pinnedAddress
|
|
401
|
+
pinnedAddress,
|
|
400
402
|
pinnedGrammarVersion: schemas_ts_1.PINNED_INTERPRETER_GRAMMAR_VERSION,
|
|
401
403
|
pinnedWasmHash: schemas_ts_1.PINNED_INTERPRETER_WASM_SHA256,
|
|
402
404
|
network,
|
|
@@ -411,41 +413,40 @@ async function runGetInterpreterInfo(raw) {
|
|
|
411
413
|
};
|
|
412
414
|
}
|
|
413
415
|
}
|
|
414
|
-
/** Build an InstallRpcClient from an optional URL override
|
|
415
|
-
* to the
|
|
416
|
-
*
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
// Default: public testnet RPC. Matches the brief; the mainnet pin would
|
|
422
|
-
// need a separate deploy and is out of scope for this tool.
|
|
423
|
-
//
|
|
416
|
+
/** Build an InstallRpcClient from an optional URL override + selected
|
|
417
|
+
* network, falling back to the pinned RPC for the network. The caller
|
|
418
|
+
* has already been gated against the pinned URL elsewhere, so the
|
|
419
|
+
* fallback here only ever picks from a finite, audited pair. */
|
|
420
|
+
function buildRpcClientFromInput(urlOverride, network) {
|
|
421
|
+
const url = urlOverride ?? schemas_ts_1.RPC_URL_BY_NETWORK[network];
|
|
422
|
+
const passphrase = schemas_ts_1.NETWORK_PASSPHRASES[network];
|
|
424
423
|
// NOT `createRpcServer` - that returns an RpcFetcher, a bare
|
|
425
424
|
// `(hash) => Promise<SorobanTxResponse|null>` for the RECORDER. Passing it
|
|
426
425
|
// here produced a client whose `getAccount` was undefined, so every live
|
|
427
426
|
// call died with "server.getAccount is not a function". The install path
|
|
428
427
|
// needs the full Server surface.
|
|
429
|
-
return (0, build_install_policy_ts_1.rpcClientFromServer)(new stellar_sdk_1.rpc.Server(
|
|
428
|
+
return (0, build_install_policy_ts_1.rpcClientFromServer)(new stellar_sdk_1.rpc.Server(url, { allowHttp: false }), passphrase);
|
|
430
429
|
}
|
|
431
430
|
/** Default-deny: refuse any interpreter policy whose address differs from
|
|
432
|
-
* the pinned
|
|
433
|
-
* can permit anything, so the smart account's
|
|
434
|
-
* to the pinned contract unless the caller
|
|
435
|
-
* `allowUnpinnedInterpreter`. OZ built-in
|
|
436
|
-
* and pass through unchanged. Returns a
|
|
437
|
-
* the run-layer envelope, or null when the
|
|
438
|
-
|
|
431
|
+
* the pinned interpreter for the selected network. An interpreter the
|
|
432
|
+
* caller controls can permit anything, so the smart account's
|
|
433
|
+
* authorization must bind to the pinned contract unless the caller
|
|
434
|
+
* explicitly opts in via `allowUnpinnedInterpreter`. OZ built-in
|
|
435
|
+
* policies are not interpreters and pass through unchanged. Returns a
|
|
436
|
+
* ToolError to surface through the run-layer envelope, or null when the
|
|
437
|
+
* policies are all pinned. The caller resolves the expected pin per
|
|
438
|
+
* network; this function stays pure so it is easy to test. */
|
|
439
|
+
function enforceInterpreterPin(policies, allowUnpinned, expectedInterpreterAddress) {
|
|
439
440
|
for (const p of policies) {
|
|
440
441
|
if (p.kind !== 'interpreter')
|
|
441
442
|
continue;
|
|
442
|
-
if (p.interpreterAddress ===
|
|
443
|
+
if (p.interpreterAddress === expectedInterpreterAddress)
|
|
443
444
|
continue;
|
|
444
445
|
if (allowUnpinned === true)
|
|
445
446
|
continue;
|
|
446
447
|
return {
|
|
447
448
|
code: 'INSTALL_BUILD_FAILED',
|
|
448
|
-
message: `install_policy: interpreter policy address ${p.interpreterAddress} != pinned ${
|
|
449
|
+
message: `install_policy: interpreter policy address ${p.interpreterAddress} != pinned ${expectedInterpreterAddress}; set allowUnpinnedInterpreter: true to opt in to a non-pinned interpreter`,
|
|
449
450
|
severity: 'error',
|
|
450
451
|
retryable: false,
|
|
451
452
|
remediation: { toolCall: { name: 'install_policy', args: {} } },
|
|
@@ -2641,9 +2641,16 @@ export declare const VerifyPolicyInputSchema: z.ZodObject<{
|
|
|
2641
2641
|
}> | undefined;
|
|
2642
2642
|
}>;
|
|
2643
2643
|
export type VerifyPolicyInput = z.infer<typeof VerifyPolicyInputSchema>;
|
|
2644
|
-
/** Pinned interpreter address (testnet). Mirrors DEPLOYMENTS.md:
|
|
2644
|
+
/** Pinned interpreter address (testnet). Mirrors DEPLOYMENTS.md:128.
|
|
2645
2645
|
* Single source for the MCP layer; do not embed elsewhere. */
|
|
2646
2646
|
export declare const PINNED_INTERPRETER_TESTNET_ADDRESS = "CDR4NLV22STCXFGZPNKDQTEANWLF7LZ6AJLY6B7CLJXKHDZGYJWIOKGP";
|
|
2647
|
+
/** Pinned interpreter address (mainnet). Mirrors DEPLOYMENTS.md:18. Mainnet
|
|
2648
|
+
* has now been deployed (2026-08-04); the mainnet interpreter IS the binary
|
|
2649
|
+
* that was exercised on testnet (same wasm sha256, see
|
|
2650
|
+
* PINNED_INTERPRETER_WASM_SHA256). The address differs because instance
|
|
2651
|
+
* ids are network-scoped. UNAUDITED at the time of writing - see
|
|
2652
|
+
* DEPLOYMENTS.md:29-32 for the recorded decision and what is still pending. */
|
|
2653
|
+
export declare const PINNED_INTERPRETER_MAINNET_ADDRESS = "CALZAMUPREIRY4TULBEXIK77AUTOEJG63XLCPUWEHHQDOVK6ZVVS7VQ2";
|
|
2647
2654
|
/** Pinned interpreter wasm sha256 (hex). Mirrors DEPLOYMENTS.md:156-157. */
|
|
2648
2655
|
export declare const PINNED_INTERPRETER_WASM_SHA256 = "6e6c13d93e197aa380303a42cd120f5ddb080dd36ef2a343ee1dbd04ca52a443";
|
|
2649
2656
|
/** The grammar version the interpreter enforces (matches SELF_VERSION in
|
|
@@ -2654,6 +2661,17 @@ export declare const PINNED_INTERPRETER_GRAMMAR_VERSION = 1;
|
|
|
2654
2661
|
* than a Server; the two are deliberately different surfaces, so this is
|
|
2655
2662
|
* pinned beside the addresses it is used with rather than shared. */
|
|
2656
2663
|
export declare const TESTNET_RPC_URL = "https://soroban-testnet.stellar.org";
|
|
2664
|
+
/** Mainnet Soroban RPC. Pinned beside MAINNET counterparts so the install
|
|
2665
|
+
* and get_interpreter_info gates compare against the matching network's
|
|
2666
|
+
* RPC rather than always testnet. Public mainnet endpoint, the same one
|
|
2667
|
+
* the deploy script hit during the 2026-08-04 mainnet rollout. */
|
|
2668
|
+
export declare const MAINNET_RPC_URL = "https://mainnet.sorobanrpc.com";
|
|
2669
|
+
/** Pin + RPC lookup for the gate enforcement. The interpreters' wasm sha256
|
|
2670
|
+
* is identical across both networks (the same binary was uploaded both
|
|
2671
|
+
* places; DEPLOYMENTS.md:25-27), so `PINNED_INTERPRETER_WASM_SHA256` stays
|
|
2672
|
+
* a single constant - only the addresses and RPCs are network-scoped. */
|
|
2673
|
+
export declare const PINNED_INTERPRETER_ADDRESS_BY_NETWORK: Record<Network, string>;
|
|
2674
|
+
export declare const RPC_URL_BY_NETWORK: Record<Network, string>;
|
|
2657
2675
|
/** Soroban `valid_until` window (ledgers) added to the latest ledger when
|
|
2658
2676
|
* building the auth entry. ~25 minutes at 5s/ledger. */
|
|
2659
2677
|
export declare const DEFAULT_AUTH_VALID_UNTIL_LEDGERS = 300;
|
|
@@ -2667,6 +2685,14 @@ export declare const InstallPolicyInputSchema: z.ZodEffects<z.ZodObject<{
|
|
|
2667
2685
|
/** The signer that authorises the install (G... wallet). Used only for
|
|
2668
2686
|
* sequence number + auth nonce simulation; never persisted, never signed. */
|
|
2669
2687
|
sourceAccount: z.ZodString;
|
|
2688
|
+
/** Target network for the install. Selects which interpreter pin and
|
|
2689
|
+
* which RPC URL are valid by default. Defaults to `testnet` so the
|
|
2690
|
+
* pre-mainnet callers keep working: they were always pointing at
|
|
2691
|
+
* the testnet pin, so defaulting testnet here is the conservative
|
|
2692
|
+
* continuation, NOT a silent fall-through that bypasses the gate.
|
|
2693
|
+
* A caller that targets mainnet MUST set this to `mainnet` (the
|
|
2694
|
+
* pin and RPC pin do not move by themselves). */
|
|
2695
|
+
network: z.ZodOptional<z.ZodEnum<["mainnet", "testnet"]>>;
|
|
2670
2696
|
/** The proposed rule draft. Mirrors the core `ContextRuleDraft` shape. */
|
|
2671
2697
|
rule: z.ZodEffects<z.ZodObject<{
|
|
2672
2698
|
contextRuleType: z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{
|
|
@@ -3121,18 +3147,22 @@ export declare const InstallPolicyInputSchema: z.ZodEffects<z.ZodObject<{
|
|
|
3121
3147
|
}, z.ZodTypeAny, "passthrough">>;
|
|
3122
3148
|
/** Per-rule install nonce; 1 for a fresh install. */
|
|
3123
3149
|
installNonce: z.ZodNumber;
|
|
3124
|
-
/** Optional RPC URL override. Defaults to the
|
|
3125
|
-
*
|
|
3150
|
+
/** Optional RPC URL override. Defaults to the pinned RPC for the
|
|
3151
|
+
* selected `network` (testnet by default, mainnet when
|
|
3152
|
+
* `network: 'mainnet'`); the override is refused unless
|
|
3126
3153
|
* `allowUnpinnedRpcUrl: true`, because the auth nonce and
|
|
3127
3154
|
* rootInvocation in the response come from whichever RPC answered. */
|
|
3128
3155
|
rpcUrl: z.ZodOptional<z.ZodString>;
|
|
3129
3156
|
/** Opt-in to using a non-pinned RPC URL. Without this flag the tool
|
|
3130
|
-
* refuses any `rpcUrl` other than
|
|
3131
|
-
* caller's auth-digest binds to whatever the
|
|
3157
|
+
* refuses any `rpcUrl` other than the pinned RPC for the selected
|
|
3158
|
+
* network because the caller's auth-digest binds to whatever the
|
|
3159
|
+
* RPC returned. */
|
|
3132
3160
|
allowUnpinnedRpcUrl: z.ZodOptional<z.ZodBoolean>;
|
|
3133
3161
|
/** Opt-in to pointing the rule's interpreter policy at any address
|
|
3134
|
-
* other than the pinned
|
|
3135
|
-
* that controls the interpreter can permit
|
|
3162
|
+
* other than the pinned interpreter for the selected network.
|
|
3163
|
+
* Default-deny: a caller that controls the interpreter can permit
|
|
3164
|
+
* everything. Selecting `network: 'mainnet'` is NOT an opt-in -
|
|
3165
|
+
* the mainnet pin is its own deny-by-default anchor. */
|
|
3136
3166
|
allowUnpinnedInterpreter: z.ZodOptional<z.ZodBoolean>;
|
|
3137
3167
|
/** Base fee in stroops; defaults to BASE_FEE (100). */
|
|
3138
3168
|
baseFee: z.ZodOptional<z.ZodNumber>;
|
|
@@ -3175,6 +3205,7 @@ export declare const InstallPolicyInputSchema: z.ZodEffects<z.ZodObject<{
|
|
|
3175
3205
|
} & {
|
|
3176
3206
|
[k: string]: unknown;
|
|
3177
3207
|
};
|
|
3208
|
+
network?: "mainnet" | "testnet" | undefined;
|
|
3178
3209
|
rpcUrl?: string | undefined;
|
|
3179
3210
|
allowUnpinnedRpcUrl?: boolean | undefined;
|
|
3180
3211
|
allowUnpinnedInterpreter?: boolean | undefined;
|
|
@@ -3218,6 +3249,7 @@ export declare const InstallPolicyInputSchema: z.ZodEffects<z.ZodObject<{
|
|
|
3218
3249
|
} & {
|
|
3219
3250
|
[k: string]: unknown;
|
|
3220
3251
|
};
|
|
3252
|
+
network?: "mainnet" | "testnet" | undefined;
|
|
3221
3253
|
rpcUrl?: string | undefined;
|
|
3222
3254
|
allowUnpinnedRpcUrl?: boolean | undefined;
|
|
3223
3255
|
allowUnpinnedInterpreter?: boolean | undefined;
|
|
@@ -3261,6 +3293,7 @@ export declare const InstallPolicyInputSchema: z.ZodEffects<z.ZodObject<{
|
|
|
3261
3293
|
} & {
|
|
3262
3294
|
[k: string]: unknown;
|
|
3263
3295
|
};
|
|
3296
|
+
network?: "mainnet" | "testnet" | undefined;
|
|
3264
3297
|
rpcUrl?: string | undefined;
|
|
3265
3298
|
allowUnpinnedRpcUrl?: boolean | undefined;
|
|
3266
3299
|
allowUnpinnedInterpreter?: boolean | undefined;
|
|
@@ -3304,6 +3337,7 @@ export declare const InstallPolicyInputSchema: z.ZodEffects<z.ZodObject<{
|
|
|
3304
3337
|
} & {
|
|
3305
3338
|
[k: string]: unknown;
|
|
3306
3339
|
};
|
|
3340
|
+
network?: "mainnet" | "testnet" | undefined;
|
|
3307
3341
|
rpcUrl?: string | undefined;
|
|
3308
3342
|
allowUnpinnedRpcUrl?: boolean | undefined;
|
|
3309
3343
|
allowUnpinnedInterpreter?: boolean | undefined;
|
|
@@ -3318,9 +3352,12 @@ export declare const RevokePolicyInputSchema: z.ZodEffects<z.ZodObject<{
|
|
|
3318
3352
|
* verify, since the account's source is not in this repo. Proven on
|
|
3319
3353
|
* testnet: the account's deployer can revoke. */
|
|
3320
3354
|
sourceAccount: z.ZodString;
|
|
3355
|
+
/** Target network for the revoke. Same `testnet`-default as install,
|
|
3356
|
+
* so pre-mainnet callers keep working without an explicit flag. */
|
|
3357
|
+
network: z.ZodOptional<z.ZodEnum<["mainnet", "testnet"]>>;
|
|
3321
3358
|
/** The rule id to remove from the smart account + interpreter. */
|
|
3322
3359
|
ruleId: z.ZodNumber;
|
|
3323
|
-
/** Optional RPC URL override; same pin as install. */
|
|
3360
|
+
/** Optional RPC URL override; same per-network pin as install. */
|
|
3324
3361
|
rpcUrl: z.ZodOptional<z.ZodString>;
|
|
3325
3362
|
/** Opt-in to using a non-pinned RPC URL. Same semantics as install. */
|
|
3326
3363
|
allowUnpinnedRpcUrl: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -3330,6 +3367,7 @@ export declare const RevokePolicyInputSchema: z.ZodEffects<z.ZodObject<{
|
|
|
3330
3367
|
smartAccount: string;
|
|
3331
3368
|
sourceAccount: string;
|
|
3332
3369
|
ruleId: number;
|
|
3370
|
+
network?: "mainnet" | "testnet" | undefined;
|
|
3333
3371
|
rpcUrl?: string | undefined;
|
|
3334
3372
|
allowUnpinnedRpcUrl?: boolean | undefined;
|
|
3335
3373
|
baseFee?: number | undefined;
|
|
@@ -3337,6 +3375,7 @@ export declare const RevokePolicyInputSchema: z.ZodEffects<z.ZodObject<{
|
|
|
3337
3375
|
smartAccount: string;
|
|
3338
3376
|
sourceAccount: string;
|
|
3339
3377
|
ruleId: number;
|
|
3378
|
+
network?: "mainnet" | "testnet" | undefined;
|
|
3340
3379
|
rpcUrl?: string | undefined;
|
|
3341
3380
|
allowUnpinnedRpcUrl?: boolean | undefined;
|
|
3342
3381
|
baseFee?: number | undefined;
|
|
@@ -3344,6 +3383,7 @@ export declare const RevokePolicyInputSchema: z.ZodEffects<z.ZodObject<{
|
|
|
3344
3383
|
smartAccount: string;
|
|
3345
3384
|
sourceAccount: string;
|
|
3346
3385
|
ruleId: number;
|
|
3386
|
+
network?: "mainnet" | "testnet" | undefined;
|
|
3347
3387
|
rpcUrl?: string | undefined;
|
|
3348
3388
|
allowUnpinnedRpcUrl?: boolean | undefined;
|
|
3349
3389
|
baseFee?: number | undefined;
|
|
@@ -3351,6 +3391,7 @@ export declare const RevokePolicyInputSchema: z.ZodEffects<z.ZodObject<{
|
|
|
3351
3391
|
smartAccount: string;
|
|
3352
3392
|
sourceAccount: string;
|
|
3353
3393
|
ruleId: number;
|
|
3394
|
+
network?: "mainnet" | "testnet" | undefined;
|
|
3354
3395
|
rpcUrl?: string | undefined;
|
|
3355
3396
|
allowUnpinnedRpcUrl?: boolean | undefined;
|
|
3356
3397
|
baseFee?: number | undefined;
|
package/dist-cjs/run/schemas.js
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
// imports them here so its tool-shape bindings stay in step; the CLI imports
|
|
17
17
|
// them here so it can build the same args envelope the MCP transport builds.
|
|
18
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
-
exports.ToolErrorSchema = exports.GetInterpreterInfoInputSchema = exports.RevokePolicyInputSchema = exports.InstallPolicyInputSchema = exports.NETWORK_PASSPHRASES = exports.DEFAULT_AUTH_VALID_UNTIL_LEDGERS = exports.TESTNET_RPC_URL = exports.PINNED_INTERPRETER_GRAMMAR_VERSION = exports.PINNED_INTERPRETER_WASM_SHA256 = exports.PINNED_INTERPRETER_TESTNET_ADDRESS = exports.VerifyPolicyInputSchema = exports.SimulatePolicyInputSchema = exports.OraclePriceFixtureSchema = exports.PredicateNodeSchema = exports.PredicateLeafSchema = exports.SynthesizePolicyInputSchema = exports.SynthesizePolicyRecordingInputSchema = exports.InterpreterOptionsSchema = exports.SynthesizePolicyMandateInputSchema = exports.RecordTransactionInputSchema = exports.OzAdapterConfigSchema = exports.ComposeUserResponsesSchema = exports.MandateSpecSchema = exports.RecordedTransactionSchema = exports.ParseConfidenceSchema = exports.OnChainEventSchema = exports.TokenMovementSchema = exports.ContractInvocationSchema = exports.ScValSchema = exports.NetworkSchema = void 0;
|
|
19
|
+
exports.ToolErrorSchema = exports.GetInterpreterInfoInputSchema = exports.RevokePolicyInputSchema = exports.InstallPolicyInputSchema = exports.NETWORK_PASSPHRASES = exports.DEFAULT_AUTH_VALID_UNTIL_LEDGERS = 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.VerifyPolicyInputSchema = exports.SimulatePolicyInputSchema = exports.OraclePriceFixtureSchema = exports.PredicateNodeSchema = exports.PredicateLeafSchema = exports.SynthesizePolicyInputSchema = exports.SynthesizePolicyRecordingInputSchema = exports.InterpreterOptionsSchema = exports.SynthesizePolicyMandateInputSchema = exports.RecordTransactionInputSchema = exports.OzAdapterConfigSchema = exports.ComposeUserResponsesSchema = exports.MandateSpecSchema = exports.RecordedTransactionSchema = exports.ParseConfidenceSchema = exports.OnChainEventSchema = exports.TokenMovementSchema = exports.ContractInvocationSchema = exports.ScValSchema = exports.NetworkSchema = void 0;
|
|
20
20
|
const zod_1 = require("zod");
|
|
21
21
|
const address_ts_1 = require("../synth/address.js");
|
|
22
22
|
/** Soroban `valid_until` is a u32 ledger sequence; a value above this cannot be
|
|
@@ -427,9 +427,16 @@ const MandateSpecSchemaForRule = zod_1.z
|
|
|
427
427
|
// install/revoke/get_info schemas live HERE (after the helper) so the const
|
|
428
428
|
// reference resolves at module init. They are the new tools on top of the
|
|
429
429
|
// existing four.
|
|
430
|
-
/** Pinned interpreter address (testnet). Mirrors DEPLOYMENTS.md:
|
|
430
|
+
/** Pinned interpreter address (testnet). Mirrors DEPLOYMENTS.md:128.
|
|
431
431
|
* Single source for the MCP layer; do not embed elsewhere. */
|
|
432
432
|
exports.PINNED_INTERPRETER_TESTNET_ADDRESS = 'CDR4NLV22STCXFGZPNKDQTEANWLF7LZ6AJLY6B7CLJXKHDZGYJWIOKGP';
|
|
433
|
+
/** Pinned interpreter address (mainnet). Mirrors DEPLOYMENTS.md:18. Mainnet
|
|
434
|
+
* has now been deployed (2026-08-04); the mainnet interpreter IS the binary
|
|
435
|
+
* that was exercised on testnet (same wasm sha256, see
|
|
436
|
+
* PINNED_INTERPRETER_WASM_SHA256). The address differs because instance
|
|
437
|
+
* ids are network-scoped. UNAUDITED at the time of writing - see
|
|
438
|
+
* DEPLOYMENTS.md:29-32 for the recorded decision and what is still pending. */
|
|
439
|
+
exports.PINNED_INTERPRETER_MAINNET_ADDRESS = 'CALZAMUPREIRY4TULBEXIK77AUTOEJG63XLCPUWEHHQDOVK6ZVVS7VQ2';
|
|
433
440
|
/** Pinned interpreter wasm sha256 (hex). Mirrors DEPLOYMENTS.md:156-157. */
|
|
434
441
|
exports.PINNED_INTERPRETER_WASM_SHA256 = '6e6c13d93e197aa380303a42cd120f5ddb080dd36ef2a343ee1dbd04ca52a443';
|
|
435
442
|
/** The grammar version the interpreter enforces (matches SELF_VERSION in
|
|
@@ -440,6 +447,23 @@ exports.PINNED_INTERPRETER_GRAMMAR_VERSION = 1;
|
|
|
440
447
|
* than a Server; the two are deliberately different surfaces, so this is
|
|
441
448
|
* pinned beside the addresses it is used with rather than shared. */
|
|
442
449
|
exports.TESTNET_RPC_URL = 'https://soroban-testnet.stellar.org';
|
|
450
|
+
/** Mainnet Soroban RPC. Pinned beside MAINNET counterparts so the install
|
|
451
|
+
* and get_interpreter_info gates compare against the matching network's
|
|
452
|
+
* RPC rather than always testnet. Public mainnet endpoint, the same one
|
|
453
|
+
* the deploy script hit during the 2026-08-04 mainnet rollout. */
|
|
454
|
+
exports.MAINNET_RPC_URL = 'https://mainnet.sorobanrpc.com';
|
|
455
|
+
/** Pin + RPC lookup for the gate enforcement. The interpreters' wasm sha256
|
|
456
|
+
* is identical across both networks (the same binary was uploaded both
|
|
457
|
+
* places; DEPLOYMENTS.md:25-27), so `PINNED_INTERPRETER_WASM_SHA256` stays
|
|
458
|
+
* a single constant - only the addresses and RPCs are network-scoped. */
|
|
459
|
+
exports.PINNED_INTERPRETER_ADDRESS_BY_NETWORK = {
|
|
460
|
+
testnet: exports.PINNED_INTERPRETER_TESTNET_ADDRESS,
|
|
461
|
+
mainnet: exports.PINNED_INTERPRETER_MAINNET_ADDRESS,
|
|
462
|
+
};
|
|
463
|
+
exports.RPC_URL_BY_NETWORK = {
|
|
464
|
+
testnet: exports.TESTNET_RPC_URL,
|
|
465
|
+
mainnet: exports.MAINNET_RPC_URL,
|
|
466
|
+
};
|
|
443
467
|
/** Soroban `valid_until` window (ledgers) added to the latest ledger when
|
|
444
468
|
* building the auth entry. ~25 minutes at 5s/ledger. */
|
|
445
469
|
exports.DEFAULT_AUTH_VALID_UNTIL_LEDGERS = 300;
|
|
@@ -457,22 +481,34 @@ exports.InstallPolicyInputSchema = zod_1.z
|
|
|
457
481
|
/** The signer that authorises the install (G... wallet). Used only for
|
|
458
482
|
* sequence number + auth nonce simulation; never persisted, never signed. */
|
|
459
483
|
sourceAccount: zod_1.z.string(),
|
|
484
|
+
/** Target network for the install. Selects which interpreter pin and
|
|
485
|
+
* which RPC URL are valid by default. Defaults to `testnet` so the
|
|
486
|
+
* pre-mainnet callers keep working: they were always pointing at
|
|
487
|
+
* the testnet pin, so defaulting testnet here is the conservative
|
|
488
|
+
* continuation, NOT a silent fall-through that bypasses the gate.
|
|
489
|
+
* A caller that targets mainnet MUST set this to `mainnet` (the
|
|
490
|
+
* pin and RPC pin do not move by themselves). */
|
|
491
|
+
network: exports.NetworkSchema.optional(),
|
|
460
492
|
/** The proposed rule draft. Mirrors the core `ContextRuleDraft` shape. */
|
|
461
493
|
rule: MandateSpecSchemaForRule,
|
|
462
494
|
/** Per-rule install nonce; 1 for a fresh install. */
|
|
463
495
|
installNonce: zod_1.z.number().int().positive(),
|
|
464
|
-
/** Optional RPC URL override. Defaults to the
|
|
465
|
-
*
|
|
496
|
+
/** Optional RPC URL override. Defaults to the pinned RPC for the
|
|
497
|
+
* selected `network` (testnet by default, mainnet when
|
|
498
|
+
* `network: 'mainnet'`); the override is refused unless
|
|
466
499
|
* `allowUnpinnedRpcUrl: true`, because the auth nonce and
|
|
467
500
|
* rootInvocation in the response come from whichever RPC answered. */
|
|
468
501
|
rpcUrl: zod_1.z.string().url().optional(),
|
|
469
502
|
/** Opt-in to using a non-pinned RPC URL. Without this flag the tool
|
|
470
|
-
* refuses any `rpcUrl` other than
|
|
471
|
-
* caller's auth-digest binds to whatever the
|
|
503
|
+
* refuses any `rpcUrl` other than the pinned RPC for the selected
|
|
504
|
+
* network because the caller's auth-digest binds to whatever the
|
|
505
|
+
* RPC returned. */
|
|
472
506
|
allowUnpinnedRpcUrl: zod_1.z.boolean().optional(),
|
|
473
507
|
/** Opt-in to pointing the rule's interpreter policy at any address
|
|
474
|
-
* other than the pinned
|
|
475
|
-
* that controls the interpreter can permit
|
|
508
|
+
* other than the pinned interpreter for the selected network.
|
|
509
|
+
* Default-deny: a caller that controls the interpreter can permit
|
|
510
|
+
* everything. Selecting `network: 'mainnet'` is NOT an opt-in -
|
|
511
|
+
* the mainnet pin is its own deny-by-default anchor. */
|
|
476
512
|
allowUnpinnedInterpreter: zod_1.z.boolean().optional(),
|
|
477
513
|
/** Base fee in stroops; defaults to BASE_FEE (100). */
|
|
478
514
|
baseFee: zod_1.z.number().int().positive().optional(),
|
|
@@ -489,9 +525,12 @@ exports.RevokePolicyInputSchema = zod_1.z
|
|
|
489
525
|
* verify, since the account's source is not in this repo. Proven on
|
|
490
526
|
* testnet: the account's deployer can revoke. */
|
|
491
527
|
sourceAccount: zod_1.z.string(),
|
|
528
|
+
/** Target network for the revoke. Same `testnet`-default as install,
|
|
529
|
+
* so pre-mainnet callers keep working without an explicit flag. */
|
|
530
|
+
network: exports.NetworkSchema.optional(),
|
|
492
531
|
/** The rule id to remove from the smart account + interpreter. */
|
|
493
532
|
ruleId: zod_1.z.number().int().nonnegative(),
|
|
494
|
-
/** Optional RPC URL override; same pin as install. */
|
|
533
|
+
/** Optional RPC URL override; same per-network pin as install. */
|
|
495
534
|
rpcUrl: zod_1.z.string().url().optional(),
|
|
496
535
|
/** Opt-in to using a non-pinned RPC URL. Same semantics as install. */
|
|
497
536
|
allowUnpinnedRpcUrl: zod_1.z.boolean().optional(),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crediolabs/policy-synth",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.16",
|
|
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",
|
|
@@ -13,9 +13,12 @@
|
|
|
13
13
|
// (b) key material the server does not have, so we ship the simpler ONE-CALL
|
|
14
14
|
// shape. The wallet signature covers the change.
|
|
15
15
|
//
|
|
16
|
-
// `buildInstallPolicyXdr`
|
|
17
|
-
//
|
|
18
|
-
//
|
|
16
|
+
// `buildInstallPolicyXdr` installs the policy in ONE call. `add_context_rule`
|
|
17
|
+
// takes `policies` as a `Map<policy_address, install_param>` and the account
|
|
18
|
+
// forwards each install_param to that policy, so the interpreter stores the
|
|
19
|
+
// predicate document as part of this same transaction. Earlier revisions
|
|
20
|
+
// documented a second `interpreter.install` call; that was wrong, and issuing
|
|
21
|
+
// it fails - the account re-enters the interpreter while it is mid-install.
|
|
19
22
|
|
|
20
23
|
import { createHash } from 'node:crypto'
|
|
21
24
|
import {
|
|
@@ -216,19 +219,17 @@ export interface BuildInstallPolicyResult {
|
|
|
216
219
|
smartAccount: string
|
|
217
220
|
/** Source account (echo) - the address that must sign. */
|
|
218
221
|
sourceAccount: string
|
|
219
|
-
/** The host-call target + fn name.
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
+
/** The host-call target + fn name. This single call installs the policy
|
|
223
|
+
* outright: `add_context_rule` takes `policies` as a
|
|
224
|
+
* `Map<policy_address, install_param>`, and the account forwards each
|
|
225
|
+
* install_param to that policy. For an interpreter policy the param
|
|
226
|
+
* carries the predicate and its hash, so the interpreter stores the
|
|
227
|
+
* document as part of this transaction. There is no second call.
|
|
228
|
+
*
|
|
229
|
+
* Verified on testnet 2026-08-01: a rule created by this builder alone
|
|
230
|
+
* permits a matching operator call and denies a non-matching one with
|
|
231
|
+
* interpreter code #100 - not #206 MissingState. */
|
|
222
232
|
call: { contract: string; fn: 'add_context_rule' }
|
|
223
|
-
/** The follow-up call the caller MUST issue after this one confirms.
|
|
224
|
-
* The rule id the account assigns in call 1 is required to bind the
|
|
225
|
-
* interpreter's `install` auth context. */
|
|
226
|
-
followUp: {
|
|
227
|
-
contract: 'interpreter'
|
|
228
|
-
fn: 'install'
|
|
229
|
-
requiresRuleIdFromCallOne: true
|
|
230
|
-
hint: string
|
|
231
|
-
}
|
|
232
233
|
/** Human-readable description of the install call, decoded FROM the
|
|
233
234
|
* built unsigned XDR (not from the input args). The wallet signature
|
|
234
235
|
* binds to bytes; the review card has to bind to the same bytes, so
|
|
@@ -243,9 +244,6 @@ export interface BuildInstallPolicyResult {
|
|
|
243
244
|
rootInvocationXdr: string
|
|
244
245
|
}
|
|
245
246
|
|
|
246
|
-
const FOLLOWUP_HINT =
|
|
247
|
-
'after this tx confirms, read the rule id via account.get_context_rules_count()-1 (or get the receipt events), then call runInstallPolicy a second time with the interpreter as the target and the rule id in context_rule_ids - OR hand-build the install() call directly with the OZ auth pattern.'
|
|
248
|
-
|
|
249
247
|
/** Build the unsigned transaction envelope for `account.add_context_rule(...)`.
|
|
250
248
|
* The output XDR is signed by the wallet, not by us. */
|
|
251
249
|
export async function buildInstallPolicyXdr(
|
|
@@ -363,12 +361,6 @@ export async function buildInstallPolicyXdr(
|
|
|
363
361
|
smartAccount: args.smartAccount,
|
|
364
362
|
sourceAccount: args.sourceAccount,
|
|
365
363
|
call: { contract: args.smartAccount, fn: 'add_context_rule' },
|
|
366
|
-
followUp: {
|
|
367
|
-
contract: 'interpreter',
|
|
368
|
-
fn: 'install',
|
|
369
|
-
requiresRuleIdFromCallOne: true,
|
|
370
|
-
hint: FOLLOWUP_HINT,
|
|
371
|
-
},
|
|
372
364
|
describes,
|
|
373
365
|
authNonce: original.credentials().address().nonce().toString(),
|
|
374
366
|
authValidUntilLedger: validUntilLedger,
|