@hazbase/simplicity 0.0.2 → 0.0.4
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/README.md +101 -0
- package/dist/cli.js +102 -3
- package/dist/client/ContractFactory.d.ts +2 -1
- package/dist/client/ContractFactory.js +3 -0
- package/dist/client/DeployedContract.d.ts +16 -1
- package/dist/client/DeployedContract.js +23 -0
- package/dist/client/SimplicityClient.d.ts +39 -1
- package/dist/client/SimplicityClient.js +29 -0
- package/dist/core/artifact.js +18 -1
- package/dist/core/compiler.js +112 -8
- package/dist/core/definition.d.ts +10 -2
- package/dist/core/definition.js +132 -3
- package/dist/core/executor.js +28 -0
- package/dist/core/state.d.ts +18 -0
- package/dist/core/state.js +278 -0
- package/dist/core/types.d.ts +88 -0
- package/dist/domain/bond.d.ts +59 -0
- package/dist/domain/bond.js +128 -0
- package/dist/domain/bondValidation.d.ts +9 -0
- package/dist/domain/bondValidation.js +90 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +14 -1
- package/package.json +1 -1
package/dist/core/compiler.js
CHANGED
|
@@ -12,6 +12,7 @@ const artifact_1 = require("./artifact");
|
|
|
12
12
|
const definition_1 = require("./definition");
|
|
13
13
|
const errors_1 = require("./errors");
|
|
14
14
|
const presets_1 = require("./presets");
|
|
15
|
+
const state_1 = require("./state");
|
|
15
16
|
const templating_1 = require("./templating");
|
|
16
17
|
const toolchain_1 = require("./toolchain");
|
|
17
18
|
function parseSimcProgram(output) {
|
|
@@ -68,7 +69,18 @@ async function buildArtifact(input) {
|
|
|
68
69
|
sdkVersion: artifact_1.SDK_PACKAGE_VERSION,
|
|
69
70
|
notes: null,
|
|
70
71
|
},
|
|
71
|
-
definition: input.definition
|
|
72
|
+
definition: input.definition
|
|
73
|
+
? (0, definition_1.buildArtifactDefinitionMetadata)(input.definition, {
|
|
74
|
+
anchorMode: input.definition.anchorMode,
|
|
75
|
+
onChainAnchor: input.definition.onChainAnchor,
|
|
76
|
+
})
|
|
77
|
+
: undefined,
|
|
78
|
+
state: input.state
|
|
79
|
+
? (0, state_1.buildArtifactStateMetadata)(input.state, {
|
|
80
|
+
anchorMode: input.state.anchorMode,
|
|
81
|
+
onChainAnchor: input.state.onChainAnchor,
|
|
82
|
+
})
|
|
83
|
+
: undefined,
|
|
72
84
|
legacy: {
|
|
73
85
|
simfTemplatePath: input.sourceSimfPath,
|
|
74
86
|
params: {
|
|
@@ -80,11 +92,60 @@ async function buildArtifact(input) {
|
|
|
80
92
|
}
|
|
81
93
|
async function compileFromFile(config, input) {
|
|
82
94
|
const definition = input.definition ? await (0, definition_1.loadDefinitionInput)(input.definition) : undefined;
|
|
95
|
+
const state = input.state ? await (0, state_1.loadStateInput)(input.state) : undefined;
|
|
96
|
+
if (definition && input.templateVars?.DEFINITION_HASH !== undefined) {
|
|
97
|
+
throw new errors_1.ValidationError("DEFINITION_HASH must not be provided explicitly when definition metadata is supplied", { code: "DEFINITION_HASH_OVERRIDE_FORBIDDEN" });
|
|
98
|
+
}
|
|
99
|
+
if (definition && input.templateVars?.DEFINITION_ID !== undefined) {
|
|
100
|
+
throw new errors_1.ValidationError("DEFINITION_ID must not be provided explicitly when definition metadata is supplied", { code: "DEFINITION_ID_OVERRIDE_FORBIDDEN" });
|
|
101
|
+
}
|
|
102
|
+
if (state && input.templateVars?.STATE_HASH !== undefined) {
|
|
103
|
+
throw new errors_1.ValidationError("STATE_HASH must not be provided explicitly when state metadata is supplied", { code: "STATE_HASH_OVERRIDE_FORBIDDEN" });
|
|
104
|
+
}
|
|
105
|
+
if (state && input.templateVars?.STATE_ID !== undefined) {
|
|
106
|
+
throw new errors_1.ValidationError("STATE_ID must not be provided explicitly when state metadata is supplied", { code: "STATE_ID_OVERRIDE_FORBIDDEN" });
|
|
107
|
+
}
|
|
83
108
|
const rawSource = await (0, promises_1.readFile)(input.simfPath, "utf8");
|
|
109
|
+
let onChainAnchor;
|
|
110
|
+
let onChainStateAnchor;
|
|
111
|
+
if (input.definition?.anchorMode === "on-chain-constant-committed") {
|
|
112
|
+
const detection = (0, definition_1.detectOnChainDefinitionAnchor)(rawSource);
|
|
113
|
+
if (!rawSource.includes("{{DEFINITION_HASH}}")) {
|
|
114
|
+
throw new errors_1.ValidationError("Requested on-chain constant-committed definition anchor, but the .simf source does not contain {{DEFINITION_HASH}}", { code: "DEFINITION_HASH_PLACEHOLDER_MISSING" });
|
|
115
|
+
}
|
|
116
|
+
if (!detection.sourceVerified || !detection.helper) {
|
|
117
|
+
const code = detection.reason?.includes("called")
|
|
118
|
+
? "DEFINITION_ONCHAIN_HELPER_NOT_CALLED"
|
|
119
|
+
: "DEFINITION_ONCHAIN_HELPER_MISSING";
|
|
120
|
+
throw new errors_1.ValidationError(`Requested on-chain constant-committed definition anchor, but the .simf source does not contain the required anchor helper pattern: ${detection.reason ?? "unknown reason"}`, { code });
|
|
121
|
+
}
|
|
122
|
+
onChainAnchor = {
|
|
123
|
+
helper: detection.helper,
|
|
124
|
+
templateVar: "DEFINITION_HASH",
|
|
125
|
+
sourceVerified: true,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
if (input.state?.anchorMode === "on-chain-constant-committed") {
|
|
129
|
+
const detection = (0, state_1.detectOnChainStateAnchor)(rawSource);
|
|
130
|
+
if (!rawSource.includes("{{STATE_HASH}}")) {
|
|
131
|
+
throw new errors_1.ValidationError("Requested on-chain constant-committed state anchor, but the .simf source does not contain {{STATE_HASH}}", { code: "STATE_HASH_PLACEHOLDER_MISSING" });
|
|
132
|
+
}
|
|
133
|
+
if (!detection.sourceVerified || !detection.helper) {
|
|
134
|
+
const code = detection.reason?.includes("called")
|
|
135
|
+
? "STATE_ONCHAIN_HELPER_NOT_CALLED"
|
|
136
|
+
: "STATE_ONCHAIN_HELPER_MISSING";
|
|
137
|
+
throw new errors_1.ValidationError(`Requested on-chain constant-committed state anchor, but the .simf source does not contain the required state helper pattern: ${detection.reason ?? "unknown reason"}`, { code });
|
|
138
|
+
}
|
|
139
|
+
onChainStateAnchor = {
|
|
140
|
+
helper: detection.helper,
|
|
141
|
+
templateVar: "STATE_HASH",
|
|
142
|
+
sourceVerified: true,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
84
145
|
const templateVars = {
|
|
85
146
|
...(input.templateVars ?? {}),
|
|
86
|
-
...(definition
|
|
87
|
-
...(
|
|
147
|
+
...(definition ? { DEFINITION_HASH: definition.hash, DEFINITION_ID: definition.definitionId } : {}),
|
|
148
|
+
...(state ? { STATE_HASH: state.hash, STATE_ID: state.stateId } : {}),
|
|
88
149
|
};
|
|
89
150
|
const rendered = (0, templating_1.renderTemplate)(rawSource, templateVars);
|
|
90
151
|
const workDir = await (0, promises_1.mkdtemp)(node_path_1.default.join((0, node_os_1.tmpdir)(), "simplicity-sdk-compile-"));
|
|
@@ -94,9 +155,22 @@ async function compileFromFile(config, input) {
|
|
|
94
155
|
config,
|
|
95
156
|
renderedSimfPath: renderedPath,
|
|
96
157
|
sourceMode: "file",
|
|
97
|
-
sourceSimfPath: input.simfPath,
|
|
158
|
+
sourceSimfPath: node_path_1.default.resolve(input.simfPath),
|
|
98
159
|
templateVars,
|
|
99
|
-
definition
|
|
160
|
+
definition: definition
|
|
161
|
+
? {
|
|
162
|
+
...definition,
|
|
163
|
+
anchorMode: input.definition?.anchorMode ?? "artifact-hash-anchor",
|
|
164
|
+
onChainAnchor,
|
|
165
|
+
}
|
|
166
|
+
: undefined,
|
|
167
|
+
state: state
|
|
168
|
+
? {
|
|
169
|
+
...state,
|
|
170
|
+
anchorMode: input.state?.anchorMode ?? "artifact-hash-anchor",
|
|
171
|
+
onChainAnchor: onChainStateAnchor,
|
|
172
|
+
}
|
|
173
|
+
: undefined,
|
|
100
174
|
});
|
|
101
175
|
if (input.artifactPath) {
|
|
102
176
|
await (0, artifact_1.saveArtifact)(input.artifactPath, artifact);
|
|
@@ -105,11 +179,30 @@ async function compileFromFile(config, input) {
|
|
|
105
179
|
}
|
|
106
180
|
async function compileFromPreset(config, input) {
|
|
107
181
|
const preset = (0, presets_1.getPresetOrThrow)(input.preset);
|
|
182
|
+
if (input.definition?.anchorMode === "on-chain-constant-committed") {
|
|
183
|
+
throw new errors_1.UnsupportedFeatureError(`Preset '${preset.id}' does not yet support on-chain constant-committed definition anchors`, { code: "DEFINITION_ANCHOR_MODE_UNSUPPORTED_FOR_PRESET", preset: preset.id });
|
|
184
|
+
}
|
|
185
|
+
if (input.state?.anchorMode === "on-chain-constant-committed") {
|
|
186
|
+
throw new errors_1.UnsupportedFeatureError(`Preset '${preset.id}' does not yet support on-chain constant-committed state anchors`, { code: "STATE_ANCHOR_MODE_UNSUPPORTED_FOR_PRESET", preset: preset.id });
|
|
187
|
+
}
|
|
108
188
|
const definition = input.definition ? await (0, definition_1.loadDefinitionInput)(input.definition) : undefined;
|
|
189
|
+
const state = input.state ? await (0, state_1.loadStateInput)(input.state) : undefined;
|
|
190
|
+
if (definition && input.params.DEFINITION_HASH !== undefined) {
|
|
191
|
+
throw new errors_1.ValidationError("DEFINITION_HASH must not be provided explicitly when definition metadata is supplied", { code: "DEFINITION_HASH_OVERRIDE_FORBIDDEN" });
|
|
192
|
+
}
|
|
193
|
+
if (definition && input.params.DEFINITION_ID !== undefined) {
|
|
194
|
+
throw new errors_1.ValidationError("DEFINITION_ID must not be provided explicitly when definition metadata is supplied", { code: "DEFINITION_ID_OVERRIDE_FORBIDDEN" });
|
|
195
|
+
}
|
|
196
|
+
if (state && input.params.STATE_HASH !== undefined) {
|
|
197
|
+
throw new errors_1.ValidationError("STATE_HASH must not be provided explicitly when state metadata is supplied", { code: "STATE_HASH_OVERRIDE_FORBIDDEN" });
|
|
198
|
+
}
|
|
199
|
+
if (state && input.params.STATE_ID !== undefined) {
|
|
200
|
+
throw new errors_1.ValidationError("STATE_ID must not be provided explicitly when state metadata is supplied", { code: "STATE_ID_OVERRIDE_FORBIDDEN" });
|
|
201
|
+
}
|
|
109
202
|
const params = {
|
|
110
203
|
...(0, presets_1.validatePresetParams)(preset, input.params),
|
|
111
|
-
...(definition
|
|
112
|
-
...(
|
|
204
|
+
...(definition ? { DEFINITION_HASH: definition.hash, DEFINITION_ID: definition.definitionId } : {}),
|
|
205
|
+
...(state ? { STATE_HASH: state.hash, STATE_ID: state.stateId } : {}),
|
|
113
206
|
};
|
|
114
207
|
const rawSource = await (0, promises_1.readFile)(preset.simfTemplatePath, "utf8");
|
|
115
208
|
const rendered = (0, templating_1.renderTemplate)(rawSource, params);
|
|
@@ -123,7 +216,18 @@ async function compileFromPreset(config, input) {
|
|
|
123
216
|
sourceSimfPath: preset.simfTemplatePath,
|
|
124
217
|
preset: preset.id,
|
|
125
218
|
templateVars: params,
|
|
126
|
-
definition
|
|
219
|
+
definition: definition
|
|
220
|
+
? {
|
|
221
|
+
...definition,
|
|
222
|
+
anchorMode: input.definition?.anchorMode ?? "artifact-hash-anchor",
|
|
223
|
+
}
|
|
224
|
+
: undefined,
|
|
225
|
+
state: state
|
|
226
|
+
? {
|
|
227
|
+
...state,
|
|
228
|
+
anchorMode: input.state?.anchorMode ?? "artifact-hash-anchor",
|
|
229
|
+
}
|
|
230
|
+
: undefined,
|
|
127
231
|
});
|
|
128
232
|
if (input.artifactPath) {
|
|
129
233
|
await (0, artifact_1.saveArtifact)(input.artifactPath, artifact);
|
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
import { ArtifactDefinitionMetadata, DefinitionDescriptor, DefinitionInput, DefinitionVerificationResult, SimplicityArtifact } from "./types";
|
|
1
|
+
import { ArtifactDefinitionMetadata, DefinitionAnchorMode, DefinitionDescriptor, DefinitionInput, DefinitionVerificationResult, SimplicityArtifact } from "./types";
|
|
2
2
|
export declare function loadDefinitionInput(input: DefinitionInput): Promise<DefinitionDescriptor>;
|
|
3
|
-
export declare function
|
|
3
|
+
export declare function detectOnChainDefinitionAnchor(simfSource: string): {
|
|
4
|
+
sourceVerified: boolean;
|
|
5
|
+
helper?: "nonzero-eq_256";
|
|
6
|
+
reason?: string;
|
|
7
|
+
};
|
|
8
|
+
export declare function buildArtifactDefinitionMetadata(definition: DefinitionDescriptor, options?: {
|
|
9
|
+
anchorMode?: DefinitionAnchorMode;
|
|
10
|
+
onChainAnchor?: ArtifactDefinitionMetadata["onChainAnchor"];
|
|
11
|
+
}): ArtifactDefinitionMetadata;
|
|
4
12
|
export declare function verifyDefinitionDescriptorAgainstArtifact(definition: DefinitionDescriptor, artifactDefinition?: ArtifactDefinitionMetadata, expectedType?: string, expectedId?: string): DefinitionVerificationResult;
|
|
5
13
|
export declare function verifyDefinitionAgainstArtifact(input: {
|
|
6
14
|
artifact: SimplicityArtifact;
|
package/dist/core/definition.js
CHANGED
|
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.loadDefinitionInput = loadDefinitionInput;
|
|
7
|
+
exports.detectOnChainDefinitionAnchor = detectOnChainDefinitionAnchor;
|
|
7
8
|
exports.buildArtifactDefinitionMetadata = buildArtifactDefinitionMetadata;
|
|
8
9
|
exports.verifyDefinitionDescriptorAgainstArtifact = verifyDefinitionDescriptorAgainstArtifact;
|
|
9
10
|
exports.verifyDefinitionAgainstArtifact = verifyDefinitionAgainstArtifact;
|
|
@@ -12,6 +13,35 @@ const node_path_1 = __importDefault(require("node:path"));
|
|
|
12
13
|
const errors_1 = require("./errors");
|
|
13
14
|
const summary_1 = require("./summary");
|
|
14
15
|
const DEFAULT_SCHEMA_VERSION = "1";
|
|
16
|
+
const DEFAULT_ANCHOR_MODE = "artifact-hash-anchor";
|
|
17
|
+
const ZERO_HASH_256 = "0x0000000000000000000000000000000000000000000000000000000000000000";
|
|
18
|
+
function stripComments(source) {
|
|
19
|
+
return source
|
|
20
|
+
.replace(/\/\*[\s\S]*?\*\//g, "")
|
|
21
|
+
.replace(/(^|[^:])\/\/.*$/gm, "$1");
|
|
22
|
+
}
|
|
23
|
+
function extractFunctionBody(source, functionName) {
|
|
24
|
+
const marker = `fn ${functionName}()`;
|
|
25
|
+
const start = source.indexOf(marker);
|
|
26
|
+
if (start === -1)
|
|
27
|
+
return null;
|
|
28
|
+
const braceStart = source.indexOf("{", start);
|
|
29
|
+
if (braceStart === -1)
|
|
30
|
+
return null;
|
|
31
|
+
let depth = 0;
|
|
32
|
+
for (let i = braceStart; i < source.length; i += 1) {
|
|
33
|
+
const char = source[i];
|
|
34
|
+
if (char === "{")
|
|
35
|
+
depth += 1;
|
|
36
|
+
if (char === "}") {
|
|
37
|
+
depth -= 1;
|
|
38
|
+
if (depth === 0) {
|
|
39
|
+
return source.slice(braceStart + 1, i);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
15
45
|
function assertNonEmpty(value, fieldName) {
|
|
16
46
|
if (!value || value.trim().length === 0) {
|
|
17
47
|
throw new errors_1.DefinitionError(`${fieldName} must not be empty`);
|
|
@@ -77,22 +107,58 @@ async function loadDefinitionInput(input) {
|
|
|
77
107
|
sourcePath,
|
|
78
108
|
};
|
|
79
109
|
}
|
|
80
|
-
function
|
|
110
|
+
function detectOnChainDefinitionAnchor(simfSource) {
|
|
111
|
+
const source = stripComments(simfSource.replace(/\r\n/g, "\n"));
|
|
112
|
+
if (!source.includes("{{DEFINITION_HASH}}")) {
|
|
113
|
+
return { sourceVerified: false, reason: "DEFINITION_HASH placeholder is missing" };
|
|
114
|
+
}
|
|
115
|
+
const helperBody = extractFunctionBody(source, "require_definition_anchor");
|
|
116
|
+
if (!helperBody) {
|
|
117
|
+
return { sourceVerified: false, reason: "Required anchor helper function is missing" };
|
|
118
|
+
}
|
|
119
|
+
if (!helperBody.includes("let anchored_definition_hash: u256 = 0x{{DEFINITION_HASH}};")) {
|
|
120
|
+
return { sourceVerified: false, reason: "Required anchored_definition_hash assignment is missing" };
|
|
121
|
+
}
|
|
122
|
+
if (!helperBody.includes(`let zero_hash: u256 = ${ZERO_HASH_256};`)) {
|
|
123
|
+
return { sourceVerified: false, reason: "Required zero_hash assignment is missing" };
|
|
124
|
+
}
|
|
125
|
+
if (!helperBody.includes("assert!(not(jet::eq_256(anchored_definition_hash, zero_hash)));")) {
|
|
126
|
+
return { sourceVerified: false, reason: "Required eq_256 assertion is missing" };
|
|
127
|
+
}
|
|
128
|
+
const mainBody = extractFunctionBody(source, "main");
|
|
129
|
+
if (!mainBody) {
|
|
130
|
+
return { sourceVerified: false, reason: "main function is missing" };
|
|
131
|
+
}
|
|
132
|
+
if (!mainBody.includes("require_definition_anchor();")) {
|
|
133
|
+
return { sourceVerified: false, reason: "require_definition_anchor() is not called from main" };
|
|
134
|
+
}
|
|
135
|
+
return { sourceVerified: true, helper: "nonzero-eq_256" };
|
|
136
|
+
}
|
|
137
|
+
function buildArtifactDefinitionMetadata(definition, options) {
|
|
81
138
|
return {
|
|
82
139
|
definitionType: definition.definitionType,
|
|
83
140
|
definitionId: definition.definitionId,
|
|
84
141
|
schemaVersion: definition.schemaVersion,
|
|
85
142
|
hash: definition.hash,
|
|
86
143
|
trustMode: "hash-anchor",
|
|
144
|
+
anchorMode: options?.anchorMode ?? DEFAULT_ANCHOR_MODE,
|
|
145
|
+
onChainAnchor: options?.onChainAnchor,
|
|
87
146
|
};
|
|
88
147
|
}
|
|
89
148
|
function verifyDefinitionDescriptorAgainstArtifact(definition, artifactDefinition, expectedType, expectedId) {
|
|
149
|
+
const noDefinitionTrust = {
|
|
150
|
+
artifactMatch: false,
|
|
151
|
+
onChainAnchorPresent: false,
|
|
152
|
+
onChainAnchorVerified: false,
|
|
153
|
+
effectiveMode: "none",
|
|
154
|
+
};
|
|
90
155
|
if (expectedType && expectedType !== definition.definitionType) {
|
|
91
156
|
return {
|
|
92
157
|
ok: false,
|
|
93
158
|
reason: `Definition type mismatch: expected=${expectedType} actual=${definition.definitionType}`,
|
|
94
159
|
definition,
|
|
95
160
|
artifactDefinition,
|
|
161
|
+
trust: noDefinitionTrust,
|
|
96
162
|
};
|
|
97
163
|
}
|
|
98
164
|
if (expectedId && expectedId !== definition.definitionId) {
|
|
@@ -101,6 +167,7 @@ function verifyDefinitionDescriptorAgainstArtifact(definition, artifactDefinitio
|
|
|
101
167
|
reason: `Definition id mismatch: expected=${expectedId} actual=${definition.definitionId}`,
|
|
102
168
|
definition,
|
|
103
169
|
artifactDefinition,
|
|
170
|
+
trust: noDefinitionTrust,
|
|
104
171
|
};
|
|
105
172
|
}
|
|
106
173
|
if (!artifactDefinition) {
|
|
@@ -108,14 +175,22 @@ function verifyDefinitionDescriptorAgainstArtifact(definition, artifactDefinitio
|
|
|
108
175
|
ok: false,
|
|
109
176
|
reason: "Artifact does not contain definition metadata",
|
|
110
177
|
definition,
|
|
178
|
+
trust: noDefinitionTrust,
|
|
111
179
|
};
|
|
112
180
|
}
|
|
181
|
+
const trust = {
|
|
182
|
+
artifactMatch: false,
|
|
183
|
+
onChainAnchorPresent: artifactDefinition.anchorMode === "on-chain-constant-committed",
|
|
184
|
+
onChainAnchorVerified: false,
|
|
185
|
+
effectiveMode: artifactDefinition.anchorMode,
|
|
186
|
+
};
|
|
113
187
|
if (artifactDefinition.definitionType !== definition.definitionType) {
|
|
114
188
|
return {
|
|
115
189
|
ok: false,
|
|
116
190
|
reason: `Definition type mismatch: artifact=${artifactDefinition.definitionType} actual=${definition.definitionType}`,
|
|
117
191
|
definition,
|
|
118
192
|
artifactDefinition,
|
|
193
|
+
trust,
|
|
119
194
|
};
|
|
120
195
|
}
|
|
121
196
|
if (artifactDefinition.definitionId !== definition.definitionId) {
|
|
@@ -124,6 +199,7 @@ function verifyDefinitionDescriptorAgainstArtifact(definition, artifactDefinitio
|
|
|
124
199
|
reason: `Definition id mismatch: artifact=${artifactDefinition.definitionId} actual=${definition.definitionId}`,
|
|
125
200
|
definition,
|
|
126
201
|
artifactDefinition,
|
|
202
|
+
trust,
|
|
127
203
|
};
|
|
128
204
|
}
|
|
129
205
|
if (artifactDefinition.schemaVersion !== definition.schemaVersion) {
|
|
@@ -132,6 +208,7 @@ function verifyDefinitionDescriptorAgainstArtifact(definition, artifactDefinitio
|
|
|
132
208
|
reason: `Definition schemaVersion mismatch: artifact=${artifactDefinition.schemaVersion} actual=${definition.schemaVersion}`,
|
|
133
209
|
definition,
|
|
134
210
|
artifactDefinition,
|
|
211
|
+
trust,
|
|
135
212
|
};
|
|
136
213
|
}
|
|
137
214
|
if (artifactDefinition.hash !== definition.hash) {
|
|
@@ -140,11 +217,63 @@ function verifyDefinitionDescriptorAgainstArtifact(definition, artifactDefinitio
|
|
|
140
217
|
reason: `Definition hash mismatch: artifact=${artifactDefinition.hash} actual=${definition.hash}`,
|
|
141
218
|
definition,
|
|
142
219
|
artifactDefinition,
|
|
220
|
+
trust,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
return {
|
|
224
|
+
ok: true,
|
|
225
|
+
definition,
|
|
226
|
+
artifactDefinition,
|
|
227
|
+
trust: {
|
|
228
|
+
...trust,
|
|
229
|
+
artifactMatch: true,
|
|
230
|
+
},
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
async function resolveDefinitionTrust(artifact, baseTrust) {
|
|
234
|
+
if (!artifact.definition) {
|
|
235
|
+
return {
|
|
236
|
+
artifactMatch: false,
|
|
237
|
+
onChainAnchorPresent: false,
|
|
238
|
+
onChainAnchorVerified: false,
|
|
239
|
+
effectiveMode: "none",
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
if (artifact.definition.anchorMode !== "on-chain-constant-committed") {
|
|
243
|
+
return baseTrust;
|
|
244
|
+
}
|
|
245
|
+
if (artifact.source.mode !== "file" || !artifact.source.simfPath) {
|
|
246
|
+
return {
|
|
247
|
+
...baseTrust,
|
|
248
|
+
onChainAnchorPresent: true,
|
|
249
|
+
onChainAnchorVerified: false,
|
|
250
|
+
effectiveMode: "on-chain-constant-committed",
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
try {
|
|
254
|
+
const source = await (0, promises_1.readFile)(artifact.source.simfPath, "utf8");
|
|
255
|
+
const detection = detectOnChainDefinitionAnchor(source);
|
|
256
|
+
return {
|
|
257
|
+
...baseTrust,
|
|
258
|
+
onChainAnchorPresent: true,
|
|
259
|
+
onChainAnchorVerified: detection.sourceVerified === true,
|
|
260
|
+
effectiveMode: "on-chain-constant-committed",
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
return {
|
|
265
|
+
...baseTrust,
|
|
266
|
+
onChainAnchorPresent: true,
|
|
267
|
+
onChainAnchorVerified: false,
|
|
268
|
+
effectiveMode: "on-chain-constant-committed",
|
|
143
269
|
};
|
|
144
270
|
}
|
|
145
|
-
return { ok: true, definition, artifactDefinition };
|
|
146
271
|
}
|
|
147
272
|
async function verifyDefinitionAgainstArtifact(input) {
|
|
148
273
|
const definition = await loadDefinitionInput(input.definition);
|
|
149
|
-
|
|
274
|
+
const result = verifyDefinitionDescriptorAgainstArtifact(definition, input.artifact.definition, input.expectedType, input.expectedId);
|
|
275
|
+
return {
|
|
276
|
+
...result,
|
|
277
|
+
trust: await resolveDefinitionTrust(input.artifact, result.trust),
|
|
278
|
+
};
|
|
150
279
|
}
|
package/dist/core/executor.js
CHANGED
|
@@ -211,6 +211,14 @@ function buildPsetSummary(decoded, meta) {
|
|
|
211
211
|
id: meta.definitionId ?? null,
|
|
212
212
|
hash: meta.definitionHash ?? null,
|
|
213
213
|
trustMode: meta.definitionTrustMode ?? null,
|
|
214
|
+
anchorMode: meta.definitionAnchorMode ?? null,
|
|
215
|
+
},
|
|
216
|
+
state: {
|
|
217
|
+
type: meta.stateType ?? null,
|
|
218
|
+
id: meta.stateId ?? null,
|
|
219
|
+
hash: meta.stateHash ?? null,
|
|
220
|
+
trustMode: meta.stateTrustMode ?? null,
|
|
221
|
+
anchorMode: meta.stateAnchorMode ?? null,
|
|
214
222
|
},
|
|
215
223
|
contract: {
|
|
216
224
|
address: meta.contractAddress,
|
|
@@ -302,6 +310,12 @@ async function buildExecutionState(config, artifact, input) {
|
|
|
302
310
|
definitionId: artifact.definition?.definitionId,
|
|
303
311
|
definitionHash: artifact.definition?.hash,
|
|
304
312
|
definitionTrustMode: artifact.definition?.trustMode,
|
|
313
|
+
definitionAnchorMode: artifact.definition?.anchorMode,
|
|
314
|
+
stateType: artifact.state?.stateType,
|
|
315
|
+
stateId: artifact.state?.stateId,
|
|
316
|
+
stateHash: artifact.state?.hash,
|
|
317
|
+
stateTrustMode: artifact.state?.trustMode,
|
|
318
|
+
stateAnchorMode: artifact.state?.anchorMode,
|
|
305
319
|
expectedLiquidReceiver: input.expectedLiquidReceiver ?? recipientAddress,
|
|
306
320
|
contractAddress: artifact.compiled.contractAddress,
|
|
307
321
|
cmr: artifact.compiled.cmr,
|
|
@@ -457,6 +471,12 @@ async function executeGaslessContractCall(config, artifact, input) {
|
|
|
457
471
|
definitionId: artifact.definition?.definitionId,
|
|
458
472
|
definitionHash: artifact.definition?.hash,
|
|
459
473
|
definitionTrustMode: artifact.definition?.trustMode,
|
|
474
|
+
definitionAnchorMode: artifact.definition?.anchorMode,
|
|
475
|
+
stateType: artifact.state?.stateType,
|
|
476
|
+
stateId: artifact.state?.stateId,
|
|
477
|
+
stateHash: artifact.state?.hash,
|
|
478
|
+
stateTrustMode: artifact.state?.trustMode,
|
|
479
|
+
stateAnchorMode: artifact.state?.anchorMode,
|
|
460
480
|
contractAddress: artifact.compiled.contractAddress,
|
|
461
481
|
cmr: artifact.compiled.cmr,
|
|
462
482
|
internalKey: artifact.compiled.internalKey,
|
|
@@ -648,6 +668,14 @@ async function executeRelayedGaslessContractCall(config, artifact, input, relaye
|
|
|
648
668
|
id: artifact.definition?.definitionId ?? null,
|
|
649
669
|
hash: artifact.definition?.hash ?? null,
|
|
650
670
|
trustMode: artifact.definition?.trustMode ?? null,
|
|
671
|
+
anchorMode: artifact.definition?.anchorMode ?? null,
|
|
672
|
+
},
|
|
673
|
+
state: {
|
|
674
|
+
type: artifact.state?.stateType ?? null,
|
|
675
|
+
id: artifact.state?.stateId ?? null,
|
|
676
|
+
hash: artifact.state?.hash ?? null,
|
|
677
|
+
trustMode: artifact.state?.trustMode ?? null,
|
|
678
|
+
anchorMode: artifact.state?.anchorMode ?? null,
|
|
651
679
|
},
|
|
652
680
|
contract: {
|
|
653
681
|
address: request.detailedSummary.contract.contractAddress,
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ArtifactStateMetadata, DefinitionAnchorMode, SimplicityArtifact, StateDocumentDescriptor, StateDocumentInput, StateVerificationResult } from "./types";
|
|
2
|
+
export declare function loadStateInput(input: StateDocumentInput): Promise<StateDocumentDescriptor>;
|
|
3
|
+
export declare function detectOnChainStateAnchor(simfSource: string): {
|
|
4
|
+
sourceVerified: boolean;
|
|
5
|
+
helper?: "nonzero-eq_256";
|
|
6
|
+
reason?: string;
|
|
7
|
+
};
|
|
8
|
+
export declare function buildArtifactStateMetadata(state: StateDocumentDescriptor, options?: {
|
|
9
|
+
anchorMode?: DefinitionAnchorMode;
|
|
10
|
+
onChainAnchor?: ArtifactStateMetadata["onChainAnchor"];
|
|
11
|
+
}): ArtifactStateMetadata;
|
|
12
|
+
export declare function verifyStateDescriptorAgainstArtifact(state: StateDocumentDescriptor, artifactState?: ArtifactStateMetadata, expectedType?: string, expectedId?: string): StateVerificationResult;
|
|
13
|
+
export declare function verifyStateAgainstArtifact(input: {
|
|
14
|
+
artifact: SimplicityArtifact;
|
|
15
|
+
state: StateDocumentInput;
|
|
16
|
+
expectedType?: string;
|
|
17
|
+
expectedId?: string;
|
|
18
|
+
}): Promise<StateVerificationResult>;
|