@crediolabs/policy-synth 0.1.13 → 0.1.15
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 +87 -60
- package/dist/install/build-install-predicate.d.ts +96 -0
- package/dist/install/build-install-predicate.js +444 -0
- package/dist/install/oz-auth.d.ts +27 -0
- package/dist/install/oz-auth.js +105 -0
- package/dist/run/index.d.ts +3 -3
- package/dist/run/index.js +3 -3
- package/dist-cjs/install/build-install-policy.d.ts +10 -12
- package/dist-cjs/install/build-install-policy.js +87 -60
- package/dist-cjs/install/build-install-predicate.d.ts +96 -0
- package/dist-cjs/install/build-install-predicate.js +479 -0
- package/dist-cjs/install/oz-auth.d.ts +27 -0
- package/dist-cjs/install/oz-auth.js +114 -0
- package/dist-cjs/run/index.d.ts +3 -3
- package/dist-cjs/run/index.js +3 -3
- package/package.json +1 -1
- package/src/install/build-install-policy.ts +155 -96
- package/src/install/oz-auth.ts +140 -0
- package/src/run/index.ts +3 -3
|
@@ -14,9 +14,12 @@
|
|
|
14
14
|
// (b) key material the server does not have, so we ship the simpler ONE-CALL
|
|
15
15
|
// shape. The wallet signature covers the change.
|
|
16
16
|
//
|
|
17
|
-
// `buildInstallPolicyXdr`
|
|
18
|
-
//
|
|
19
|
-
//
|
|
17
|
+
// `buildInstallPolicyXdr` installs the policy in ONE call. `add_context_rule`
|
|
18
|
+
// takes `policies` as a `Map<policy_address, install_param>` and the account
|
|
19
|
+
// forwards each install_param to that policy, so the interpreter stores the
|
|
20
|
+
// predicate document as part of this same transaction. Earlier revisions
|
|
21
|
+
// documented a second `interpreter.install` call; that was wrong, and issuing
|
|
22
|
+
// it fails - the account re-enters the interpreter while it is mid-install.
|
|
20
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
24
|
exports.DEFAULT_GRAMMAR_VERSION = exports.Contract = void 0;
|
|
22
25
|
exports.rpcClientFromServer = rpcClientFromServer;
|
|
@@ -27,6 +30,7 @@ const stellar_sdk_1 = require("@stellar/stellar-sdk");
|
|
|
27
30
|
Object.defineProperty(exports, "Contract", { enumerable: true, get: function () { return stellar_sdk_1.Contract; } });
|
|
28
31
|
const build_add_context_rule_ts_1 = require("./build-add-context-rule.js");
|
|
29
32
|
Object.defineProperty(exports, "DEFAULT_GRAMMAR_VERSION", { enumerable: true, get: function () { return build_add_context_rule_ts_1.DEFAULT_GRAMMAR_VERSION; } });
|
|
33
|
+
const oz_auth_ts_1 = require("./oz-auth.js");
|
|
30
34
|
/** Convert a real rpc.Server into the InstallRpcClient surface. The
|
|
31
35
|
* `getContractVersion` lookup uses `simulateTransaction` against
|
|
32
36
|
* `contract.call('grammar_version')` and decodes the returned u32.
|
|
@@ -70,7 +74,6 @@ function rpcClientFromServer(server, networkPassphrase) {
|
|
|
70
74
|
},
|
|
71
75
|
};
|
|
72
76
|
}
|
|
73
|
-
const FOLLOWUP_HINT = '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.';
|
|
74
77
|
/** Build the unsigned transaction envelope for `account.add_context_rule(...)`.
|
|
75
78
|
* The output XDR is signed by the wallet, not by us. */
|
|
76
79
|
async function buildInstallPolicyXdr(args) {
|
|
@@ -91,31 +94,28 @@ async function buildInstallPolicyXdr(args) {
|
|
|
91
94
|
...(args.oracleParams ? { oracleParams: args.oracleParams } : {}),
|
|
92
95
|
...(args.grammarVersion !== undefined ? { grammarVersion: args.grammarVersion } : {}),
|
|
93
96
|
});
|
|
94
|
-
// 2.
|
|
97
|
+
// 2. Fetch the source sequence, then build the recording transaction with a
|
|
98
|
+
// bare host call. The recording pass assigns the smart-account auth nonce
|
|
99
|
+
// and root invocation needed to construct OZ's AuthPayload.
|
|
95
100
|
const source = await args.rpc.getAccount(args.sourceAccount);
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
functionName: 'add_context_rule',
|
|
103
|
-
args: [...callArgs],
|
|
104
|
-
})),
|
|
105
|
-
auth: [],
|
|
106
|
-
});
|
|
101
|
+
const hostFunction = stellar_sdk_1.xdr.HostFunction.hostFunctionTypeInvokeContract(new stellar_sdk_1.xdr.InvokeContractArgs({
|
|
102
|
+
contractAddress: new stellar_sdk_1.Address(args.smartAccount).toScAddress(),
|
|
103
|
+
functionName: 'add_context_rule',
|
|
104
|
+
args: [...callArgs],
|
|
105
|
+
}));
|
|
106
|
+
const makeOperation = (auth = []) => stellar_sdk_1.Operation.invokeHostFunction({ func: hostFunction, auth });
|
|
107
107
|
const baseFee = args.baseFee !== undefined ? String(args.baseFee) : stellar_sdk_1.BASE_FEE;
|
|
108
|
-
const
|
|
108
|
+
const buildTx = (op) => buildUnsignedTx({
|
|
109
109
|
sourceAccount: args.sourceAccount,
|
|
110
110
|
sequence: source.sequenceNumber(),
|
|
111
111
|
fee: baseFee,
|
|
112
112
|
networkPassphrase: args.networkPassphrase,
|
|
113
113
|
op,
|
|
114
114
|
});
|
|
115
|
-
|
|
116
|
-
//
|
|
117
|
-
//
|
|
118
|
-
const recorded = await args.rpc.simulateTransaction(
|
|
115
|
+
const recordingTx = buildTx(makeOperation());
|
|
116
|
+
// 3. Recording simulation: capture the smart account's nonce and invocation
|
|
117
|
+
// tree. Nothing is signed here.
|
|
118
|
+
const recorded = await args.rpc.simulateTransaction(recordingTx);
|
|
119
119
|
if (stellar_sdk_1.rpc.Api.isSimulationError(recorded)) {
|
|
120
120
|
// Short, stable reason. The full `simulateTransaction` error (which
|
|
121
121
|
// carries host + URL detail) stays in the SDK's own logs - never
|
|
@@ -129,23 +129,35 @@ async function buildInstallPolicyXdr(args) {
|
|
|
129
129
|
if (!original) {
|
|
130
130
|
throw new Error(`install_policy: no Soroban auth entry for smart account ${args.smartAccount}; this call does not route through the smart account`);
|
|
131
131
|
}
|
|
132
|
-
//
|
|
133
|
-
//
|
|
134
|
-
//
|
|
135
|
-
//
|
|
136
|
-
|
|
137
|
-
|
|
132
|
+
// 4. `add_context_rule` is authorised by the deploy-time admin rule (rule 0).
|
|
133
|
+
// The delegated signer uses source-account credentials, so its signature
|
|
134
|
+
// bytes stay empty and the ordinary transaction-envelope signature covers
|
|
135
|
+
// the call when the consumer signs it.
|
|
136
|
+
const validUntilLedger = (await args.rpc.getLatestLedger()).sequence +
|
|
137
|
+
(args.authValidUntilLedgers ?? DEFAULT_AUTH_VALID_UNTIL_LEDGERS);
|
|
138
|
+
const contextRuleIds = [0];
|
|
139
|
+
const digest = (0, oz_auth_ts_1.authDigest)((0, oz_auth_ts_1.signaturePayload)(args.networkPassphrase, original.credentials().address().nonce(), validUntilLedger, original.rootInvocation()), contextRuleIds);
|
|
140
|
+
const authEntries = [
|
|
141
|
+
(0, oz_auth_ts_1.accountEntry)(original, validUntilLedger, (0, oz_auth_ts_1.authPayload)([args.sourceAccount], contextRuleIds, () => Buffer.alloc(0))),
|
|
142
|
+
...contextRuleIds.map(() => (0, oz_auth_ts_1.delegatedSignerEntry)(args.smartAccount, digest)),
|
|
143
|
+
];
|
|
144
|
+
// 5. Simulate again with the OZ entries already attached. The SDK preserves
|
|
145
|
+
// existing auth during assembly and adds the simulated Soroban footprint +
|
|
146
|
+
// resource fee, yielding a complete unsigned envelope.
|
|
147
|
+
const txWithAuth = buildTx(makeOperation(authEntries));
|
|
148
|
+
const enforcing = await args.rpc.simulateTransaction(txWithAuth);
|
|
149
|
+
if (stellar_sdk_1.rpc.Api.isSimulationError(enforcing)) {
|
|
150
|
+
throw new Error('install_policy: auth simulateTransaction failed');
|
|
151
|
+
}
|
|
152
|
+
const finalTx = stellar_sdk_1.rpc.assembleTransaction(txWithAuth, enforcing).build();
|
|
153
|
+
// 6. Decode the structured description FROM the final assembled transaction.
|
|
154
|
+
// The human approval binds to the exact bytes the wallet will sign.
|
|
155
|
+
const describes = decodeInstallCallDescribes(finalTx, args.installNonce);
|
|
138
156
|
return {
|
|
139
|
-
unsignedXdr:
|
|
157
|
+
unsignedXdr: finalTx.toEnvelope().toXDR().toString('base64'),
|
|
140
158
|
smartAccount: args.smartAccount,
|
|
141
159
|
sourceAccount: args.sourceAccount,
|
|
142
160
|
call: { contract: args.smartAccount, fn: 'add_context_rule' },
|
|
143
|
-
followUp: {
|
|
144
|
-
contract: 'interpreter',
|
|
145
|
-
fn: 'install',
|
|
146
|
-
requiresRuleIdFromCallOne: true,
|
|
147
|
-
hint: FOLLOWUP_HINT,
|
|
148
|
-
},
|
|
149
161
|
describes,
|
|
150
162
|
authNonce: original.credentials().address().nonce().toString(),
|
|
151
163
|
authValidUntilLedger: validUntilLedger,
|
|
@@ -165,25 +177,21 @@ async function buildInstallPolicyXdr(args) {
|
|
|
165
177
|
* be guessing at a contract it cannot read, and the chain is the authority. */
|
|
166
178
|
async function buildRevokePolicyXdr(args) {
|
|
167
179
|
const source = await args.rpc.getAccount(args.sourceAccount);
|
|
168
|
-
const
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
args: [stellar_sdk_1.xdr.ScVal.scvU32(args.ruleId)],
|
|
175
|
-
})),
|
|
176
|
-
auth: [],
|
|
177
|
-
});
|
|
180
|
+
const hostFunction = stellar_sdk_1.xdr.HostFunction.hostFunctionTypeInvokeContract(new stellar_sdk_1.xdr.InvokeContractArgs({
|
|
181
|
+
contractAddress: new stellar_sdk_1.Address(args.smartAccount).toScAddress(),
|
|
182
|
+
functionName: 'remove_context_rule',
|
|
183
|
+
args: [stellar_sdk_1.xdr.ScVal.scvU32(args.ruleId)],
|
|
184
|
+
}));
|
|
185
|
+
const makeOperation = (auth = []) => stellar_sdk_1.Operation.invokeHostFunction({ func: hostFunction, auth });
|
|
178
186
|
const baseFee = args.baseFee !== undefined ? String(args.baseFee) : stellar_sdk_1.BASE_FEE;
|
|
179
|
-
const
|
|
187
|
+
const buildTx = (op) => buildUnsignedTx({
|
|
180
188
|
sourceAccount: args.sourceAccount,
|
|
181
189
|
sequence: source.sequenceNumber(),
|
|
182
190
|
fee: baseFee,
|
|
183
191
|
networkPassphrase: args.networkPassphrase,
|
|
184
192
|
op,
|
|
185
193
|
});
|
|
186
|
-
const recorded = await args.rpc.simulateTransaction(
|
|
194
|
+
const recorded = await args.rpc.simulateTransaction(buildTx(makeOperation()));
|
|
187
195
|
if (stellar_sdk_1.rpc.Api.isSimulationError(recorded)) {
|
|
188
196
|
// Short, stable reason. The full `simulateTransaction` error (which
|
|
189
197
|
// carries host + URL detail) stays in the SDK's own logs - never
|
|
@@ -197,8 +205,27 @@ async function buildRevokePolicyXdr(args) {
|
|
|
197
205
|
if (!original) {
|
|
198
206
|
throw new Error(`revoke_policy: no Soroban auth entry for smart account ${args.smartAccount}; this call does not route through the smart account`);
|
|
199
207
|
}
|
|
208
|
+
// Removal is master-only, so the deploy-time admin rule authorises it. The
|
|
209
|
+
// recorded rootInvocation still includes remove_context_rule(ruleId), binding
|
|
210
|
+
// the auth payload to the exact rule being removed. As with install,
|
|
211
|
+
// source-account credentials carry the delegated signer entry and the
|
|
212
|
+
// consumer supplies only the ordinary envelope signature.
|
|
213
|
+
const validUntilLedger = (await args.rpc.getLatestLedger()).sequence +
|
|
214
|
+
(args.authValidUntilLedgers ?? DEFAULT_AUTH_VALID_UNTIL_LEDGERS);
|
|
215
|
+
const contextRuleIds = [0];
|
|
216
|
+
const digest = (0, oz_auth_ts_1.authDigest)((0, oz_auth_ts_1.signaturePayload)(args.networkPassphrase, original.credentials().address().nonce(), validUntilLedger, original.rootInvocation()), contextRuleIds);
|
|
217
|
+
const authEntries = [
|
|
218
|
+
(0, oz_auth_ts_1.accountEntry)(original, validUntilLedger, (0, oz_auth_ts_1.authPayload)([args.sourceAccount], contextRuleIds, () => Buffer.alloc(0))),
|
|
219
|
+
...contextRuleIds.map(() => (0, oz_auth_ts_1.delegatedSignerEntry)(args.smartAccount, digest)),
|
|
220
|
+
];
|
|
221
|
+
const txWithAuth = buildTx(makeOperation(authEntries));
|
|
222
|
+
const enforcing = await args.rpc.simulateTransaction(txWithAuth);
|
|
223
|
+
if (stellar_sdk_1.rpc.Api.isSimulationError(enforcing)) {
|
|
224
|
+
throw new Error('revoke_policy: auth simulateTransaction failed');
|
|
225
|
+
}
|
|
226
|
+
const finalTx = stellar_sdk_1.rpc.assembleTransaction(txWithAuth, enforcing).build();
|
|
200
227
|
return {
|
|
201
|
-
unsignedXdr:
|
|
228
|
+
unsignedXdr: finalTx.toEnvelope().toXDR().toString('base64'),
|
|
202
229
|
smartAccount: args.smartAccount,
|
|
203
230
|
sourceAccount: args.sourceAccount,
|
|
204
231
|
call: { contract: args.smartAccount, fn: 'remove_context_rule', ruleId: args.ruleId },
|
|
@@ -208,7 +235,7 @@ async function buildRevokePolicyXdr(args) {
|
|
|
208
235
|
};
|
|
209
236
|
}
|
|
210
237
|
/** ~25 minutes at 5s/ledger. */
|
|
211
|
-
const
|
|
238
|
+
const DEFAULT_AUTH_VALID_UNTIL_LEDGERS = 300;
|
|
212
239
|
// ---- internals ----
|
|
213
240
|
/** Adapter: turn the install-policy wire `PolicyRef` shape into the core
|
|
214
241
|
* `PolicyRef` shape `buildAddContextRuleArgs` expects. Keeps the wire
|
|
@@ -246,20 +273,24 @@ function buildUnsignedTx(args) {
|
|
|
246
273
|
// its signature, and broadcasts. We do NOT sign here.
|
|
247
274
|
return tx;
|
|
248
275
|
}
|
|
249
|
-
/** Decode the install call's structured fields directly out of the
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
* will
|
|
253
|
-
*
|
|
254
|
-
* a ToolError, since that would mean the XDR was tampered with (or
|
|
276
|
+
/** Decode the install call's structured fields directly out of the final
|
|
277
|
+
* assembled transaction. The bytes are the source of truth: a human reviewing
|
|
278
|
+
* the install wants to see what the wallet will actually sign, not what we
|
|
279
|
+
* think it will. The decode is deliberately strict - any shape we did not
|
|
280
|
+
* build ourselves throws, since that would mean the XDR was tampered with (or
|
|
255
281
|
* the encoder changed and this descriptor lags).
|
|
256
282
|
*
|
|
257
283
|
* `expectedInstallNonce` is a fallback for the rare case where the
|
|
258
284
|
* install has no interpreter policy (no `install_nonce` to read); the
|
|
259
285
|
* caller already knows it. */
|
|
260
|
-
function decodeInstallCallDescribes(tx,
|
|
286
|
+
function decodeInstallCallDescribes(tx, expectedInstallNonce) {
|
|
287
|
+
const operations = tx.toEnvelope().v1().tx().operations();
|
|
288
|
+
if (operations.length !== 1 || !operations[0]) {
|
|
289
|
+
throw new Error(`install_policy: final transaction has ${operations.length} operations, expected 1`);
|
|
290
|
+
}
|
|
291
|
+
const op = operations[0];
|
|
261
292
|
const hostFn = op.body().invokeHostFunctionOp()?.hostFunction();
|
|
262
|
-
if (
|
|
293
|
+
if (hostFn?.switch().name !== 'hostFunctionTypeInvokeContract') {
|
|
263
294
|
throw new Error('install_policy: built op is not an invokeHostFunction(invokeContract(...)) call');
|
|
264
295
|
}
|
|
265
296
|
const invokeArgs = hostFn.invokeContract();
|
|
@@ -412,10 +443,6 @@ function decodeInstallCallDescribes(tx, op, expectedInstallNonce) {
|
|
|
412
443
|
// `observedInstallNonce` is the nonce baked into whichever interpreter
|
|
413
444
|
// policy is present; when none, fall back to the caller-supplied value.
|
|
414
445
|
const installNonce = observedInstallNonce ?? expectedInstallNonce;
|
|
415
|
-
// Touch `tx` so the linter does not flag it as unused - the parameter
|
|
416
|
-
// documents that the caller built this Transaction; we re-parse the
|
|
417
|
-
// operation off it as a sanity check.
|
|
418
|
-
void tx;
|
|
419
446
|
return {
|
|
420
447
|
targetContract,
|
|
421
448
|
fnName: 'add_context_rule',
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { Contract } from '@stellar/stellar-sdk';
|
|
2
|
+
import type { InstallRpcClient } from './build-install-policy.ts';
|
|
3
|
+
/** Inputs for the install-predicate build. */
|
|
4
|
+
export interface BuildInstallPredicateArgs {
|
|
5
|
+
/** The smart account contract address (C...). The interpreter hashes
|
|
6
|
+
* this rule's `signers` at install; we fetch it via `get_context_rule`
|
|
7
|
+
* on this address, not reconstruct it. */
|
|
8
|
+
smartAccount: string;
|
|
9
|
+
/** The signer that authorises the install (G... wallet). */
|
|
10
|
+
sourceAccount: string;
|
|
11
|
+
/** The rule id the account assigned in call 1. */
|
|
12
|
+
ruleId: number;
|
|
13
|
+
/** The interpreter contract address (C...). */
|
|
14
|
+
interpreterAddress: string;
|
|
15
|
+
/** Network passphrase - pins the hash the auth digest binds. */
|
|
16
|
+
networkPassphrase: string;
|
|
17
|
+
/** Already-encoded (base64) canonical ScVal of the predicate. */
|
|
18
|
+
encodedPredicate: string;
|
|
19
|
+
/** Hex sha256 of the canonical predicate XDR bytes. */
|
|
20
|
+
predicateHash: string;
|
|
21
|
+
/** Grammar version override; defaults to 1. */
|
|
22
|
+
grammarVersion?: number;
|
|
23
|
+
/** Base fee in stroops; defaults to BASE_FEE (100). */
|
|
24
|
+
baseFee?: number;
|
|
25
|
+
/** RPC client to use for the simulation pass; injected for tests. */
|
|
26
|
+
rpc: InstallRpcClient;
|
|
27
|
+
/** Ledger window (in ledgers) for the auth entry's `validUntil`. */
|
|
28
|
+
authValidUntilLedgers?: number;
|
|
29
|
+
}
|
|
30
|
+
/** Human-readable description of the install-predicate call, decoded FROM
|
|
31
|
+
* the built XDR (not from the input args). The wallet signature binds
|
|
32
|
+
* to bytes; the review card has to bind to the same bytes, so this is
|
|
33
|
+
* the only safe source.
|
|
34
|
+
*
|
|
35
|
+
* `ruleId` is NOT decoded from the XDR - it lives inside
|
|
36
|
+
* `raw_context_rule`, which is passed through verbatim. Decoding it
|
|
37
|
+
* here would re-introduce the client-side reconstruction the file
|
|
38
|
+
* header warns against. The top-level `BuildInstallPredicateResult`
|
|
39
|
+
* echoes the caller-supplied rule id instead. */
|
|
40
|
+
export interface InstallPredicateCallDescribes {
|
|
41
|
+
/** The interpreter that will hold the predicate. */
|
|
42
|
+
targetContract: string;
|
|
43
|
+
/** The fn name on the target (always `install` today). */
|
|
44
|
+
fnName: 'install';
|
|
45
|
+
/** Grammar version the interpreter enforces; read off the wire. */
|
|
46
|
+
grammarVersion: number;
|
|
47
|
+
/** Per-rule install nonce; read off the wire. */
|
|
48
|
+
installNonce: number;
|
|
49
|
+
/** Hex sha256 of the encoded predicate blob; read off the wire. */
|
|
50
|
+
predicateHash: string;
|
|
51
|
+
/** Hex sha256 of the predicate bytes embedded in the params map. The
|
|
52
|
+
* two values MUST match; a difference is a wire tampering signal. */
|
|
53
|
+
predicateSha256OfEmbeddedBytes: string;
|
|
54
|
+
/** The smart account address encoded in args[2], read off the wire. */
|
|
55
|
+
smartAccountOnWire: string;
|
|
56
|
+
}
|
|
57
|
+
/** Output of the install-predicate build. The unsigned XDR is the
|
|
58
|
+
* wallet's input; the wallet signs it (single envelope signature) and
|
|
59
|
+
* submits. The auth tree matches install_policy: account entry
|
|
60
|
+
* carrying OZ's AuthPayload + a source-account delegated signer entry.
|
|
61
|
+
* Both are covered by the envelope signature. */
|
|
62
|
+
export interface BuildInstallPredicateResult {
|
|
63
|
+
/** Unsigned Soroban transaction envelope, base64 XDR. */
|
|
64
|
+
unsignedXdr: string;
|
|
65
|
+
/** Smart account contract address (echo). */
|
|
66
|
+
smartAccount: string;
|
|
67
|
+
/** Source account (echo) - the address that signs the envelope. */
|
|
68
|
+
sourceAccount: string;
|
|
69
|
+
/** The interpreter contract address (echo). */
|
|
70
|
+
interpreterAddress: string;
|
|
71
|
+
/** The rule id the account assigned in call 1 (echo). */
|
|
72
|
+
ruleId: number;
|
|
73
|
+
/** The host-call target + fn name. */
|
|
74
|
+
call: {
|
|
75
|
+
contract: string;
|
|
76
|
+
fn: 'install';
|
|
77
|
+
};
|
|
78
|
+
/** The smart-account auth nonce (snapshot). */
|
|
79
|
+
authNonce: string;
|
|
80
|
+
/** The ledger sequence + window the auth entry expires at. */
|
|
81
|
+
authValidUntilLedger: number;
|
|
82
|
+
/** The captured rootInvocation for the smart-account entry. */
|
|
83
|
+
rootInvocationXdr: string;
|
|
84
|
+
/** Human-readable description of the install call, decoded FROM the
|
|
85
|
+
* built unsigned XDR (not from the input args). The wallet signature
|
|
86
|
+
* binds to bytes; the review card has to bind to the same bytes, so
|
|
87
|
+
* this is the only safe source. */
|
|
88
|
+
describes: InstallPredicateCallDescribes;
|
|
89
|
+
}
|
|
90
|
+
/** Build the unsigned transaction envelope for
|
|
91
|
+
* `interpreter.install(params, raw_context_rule, smart_account)`. The
|
|
92
|
+
* output XDR is signed by the wallet, not by us. */
|
|
93
|
+
export declare function buildInstallPredicateXdr(args: BuildInstallPredicateArgs): Promise<BuildInstallPredicateResult>;
|
|
94
|
+
/** Re-export `Contract` so the run-layer does not need to import the
|
|
95
|
+
* SDK directly. Mirrors the build-install-policy.ts convention. */
|
|
96
|
+
export { Contract };
|