@hazbase/simplicity 0.0.2 → 0.0.3

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 CHANGED
@@ -1,4 +1,6 @@
1
1
  # @hazbase/simplicity
2
+ [![npm version](https://badge.fury.io/js/@hazbase%2Fsimplicity.svg)](https://badge.fury.io/js/@hazbase%2Fsimplicity)
3
+ [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
2
4
 
3
5
  `@hazbase/simplicity` is a Node.js / TypeScript SDK for working with Simplicity contracts on Liquid with an EVM-like developer workflow. It lets you compile SimplicityHL (`.simf`) contracts, derive the contract address, fund that address, inspect the spend you are about to make, execute the contract, and optionally run fee-sponsored flows through a sponsor wallet or relayer. It also ships with built-in presets so you can start from known-good contract templates before moving to custom `.simf` code.
4
6
 
@@ -72,6 +74,13 @@ What that means:
72
74
  - injects `DEFINITION_HASH` and `DEFINITION_ID` into compile-time template vars when a definition is provided,
73
75
  - lets you verify later that the JSON you are reading still matches the contract/artifact it was compiled against.
74
76
 
77
+ There are now two anchor modes:
78
+ - `artifact-hash-anchor`: the JSON hash is anchored in the artifact and verified later against that artifact.
79
+ - `on-chain-constant-committed`: the JSON hash is anchored in the artifact and also committed into executed contract logic, so it materially affects the compiled program, CMR, and contract address.
80
+
81
+ Today, `on-chain-constant-committed` is guaranteed for custom `.simf` contracts that include the blessed `require_definition_anchor()` helper pattern. Built-in presets still default to artifact-only anchors for now.
82
+ The SDK does **not** trust artifact JSON alone for this verdict. `trust.onChainAnchorVerified` only becomes `true` when the SDK can read the source file again and re-detect the blessed helper pattern. If the source file is unavailable, the claimed mode may still be `on-chain-constant-committed`, but `onChainAnchorVerified` will remain `false`.
83
+
75
84
  Minimal TypeScript flow:
76
85
 
77
86
  ```ts
@@ -92,6 +101,7 @@ const compiled = await sdk.compileFromFile({
92
101
  id: definition.definitionId,
93
102
  schemaVersion: definition.schemaVersion,
94
103
  jsonPath: definition.sourcePath,
104
+ anchorMode: "on-chain-constant-committed",
95
105
  },
96
106
  artifactPath: "./bond.artifact.json",
97
107
  });
@@ -104,6 +114,7 @@ const verification = await sdk.verifyDefinitionAgainstArtifact({
104
114
  });
105
115
 
106
116
  console.log(verification.ok);
117
+ console.log(verification.trust.effectiveMode);
107
118
  ```
108
119
 
109
120
  CLI equivalents:
@@ -828,6 +839,7 @@ When you compile with `definition: { ... }`, the artifact also carries:
828
839
  - `schemaVersion`
829
840
  - `hash`
830
841
  - `trustMode`
842
+ - `anchorMode`
831
843
 
832
844
  That is what allows the SDK and CLI to verify that an off-chain JSON definition still matches the contract you compiled.
833
845
 
package/dist/cli.js CHANGED
@@ -72,7 +72,8 @@ function parseDefinitionInput() {
72
72
  const jsonPath = getArg("definition-json");
73
73
  const valueJson = getArg("definition-value");
74
74
  const schemaVersion = getArg("definition-schema-version");
75
- if (!type && !id && !jsonPath && !valueJson && !schemaVersion) {
75
+ const anchorMode = getArg("definition-anchor-mode");
76
+ if (!type && !id && !jsonPath && !valueJson && !schemaVersion && !anchorMode) {
76
77
  return undefined;
77
78
  }
78
79
  return {
@@ -81,6 +82,7 @@ function parseDefinitionInput() {
81
82
  schemaVersion: schemaVersion ?? undefined,
82
83
  jsonPath,
83
84
  value: valueJson ? JSON.parse(valueJson) : undefined,
85
+ anchorMode,
84
86
  };
85
87
  }
86
88
  function resolveConfig() {
@@ -382,6 +384,9 @@ function formatArtifactHelp(artifact, preset, utxos) {
382
384
  ` schema version: ${artifact.definition.schemaVersion}`,
383
385
  ` hash: ${artifact.definition.hash}`,
384
386
  ` trust mode: ${artifact.definition.trustMode}`,
387
+ ` anchor mode: ${artifact.definition.anchorMode}`,
388
+ ` on-chain helper: ${artifact.definition.onChainAnchor?.helper ?? "(none)"}`,
389
+ ` source verified: ${artifact.definition.onChainAnchor?.sourceVerified === true ? "yes" : "no"}`,
385
390
  ].join("\n")
386
391
  : " (none)";
387
392
  const compileSource = artifact.source.simfPath ?? artifact.legacy?.simfTemplatePath ?? "(unknown)";
@@ -466,7 +471,10 @@ async function main() {
466
471
  value: getArg("value") ? JSON.parse(getArg("value")) : undefined,
467
472
  schemaVersion: getArg("schema-version"),
468
473
  });
469
- printJson(definition);
474
+ printJson({
475
+ ...definition,
476
+ anchorRecommendation: "Use --definition-anchor-mode on-chain-constant-committed with a blessed custom .simf helper for on-chain enforcement",
477
+ });
470
478
  return;
471
479
  }
472
480
  if (command === "definition" && subcommand === "verify") {
@@ -485,6 +493,7 @@ async function main() {
485
493
  reason: verification.reason,
486
494
  definition: verification.definition,
487
495
  artifactDefinition: verification.artifactDefinition ?? null,
496
+ trust: verification.trust,
488
497
  });
489
498
  return;
490
499
  }
@@ -21,5 +21,6 @@ export declare class DeployedContract {
21
21
  definition: Awaited<ReturnType<typeof verifyDefinitionAgainstArtifact>>["definition"];
22
22
  artifactDefinition: ArtifactDefinitionMetadata | null;
23
23
  reason?: string;
24
+ trust: Awaited<ReturnType<typeof verifyDefinitionAgainstArtifact>>["trust"];
24
25
  }>;
25
26
  }
@@ -58,6 +58,7 @@ class DeployedContract {
58
58
  definition: verification.definition,
59
59
  artifactDefinition: verification.artifactDefinition ?? null,
60
60
  reason: verification.reason,
61
+ trust: verification.trust,
61
62
  };
62
63
  }
63
64
  }
@@ -17,7 +17,16 @@ function isArtifactV5(value) {
17
17
  }
18
18
  function normalizeArtifact(artifact, networkDefault = "liquidtestnet") {
19
19
  if (artifact.version === exports.SDK_ARTIFACT_VERSION) {
20
- return artifact;
20
+ const current = artifact;
21
+ return {
22
+ ...current,
23
+ definition: current.definition
24
+ ? {
25
+ ...current.definition,
26
+ anchorMode: current.definition.anchorMode ?? "artifact-hash-anchor",
27
+ }
28
+ : undefined,
29
+ };
21
30
  }
22
31
  if (!isArtifactV5(artifact)) {
23
32
  throw new errors_1.ArtifactError("Unsupported artifact version", artifact);
@@ -68,7 +68,12 @@ async function buildArtifact(input) {
68
68
  sdkVersion: artifact_1.SDK_PACKAGE_VERSION,
69
69
  notes: null,
70
70
  },
71
- definition: input.definition ? (0, definition_1.buildArtifactDefinitionMetadata)(input.definition) : undefined,
71
+ definition: input.definition
72
+ ? (0, definition_1.buildArtifactDefinitionMetadata)(input.definition, {
73
+ anchorMode: input.definition.anchorMode,
74
+ onChainAnchor: input.definition.onChainAnchor,
75
+ })
76
+ : undefined,
72
77
  legacy: {
73
78
  simfTemplatePath: input.sourceSimfPath,
74
79
  params: {
@@ -80,7 +85,31 @@ async function buildArtifact(input) {
80
85
  }
81
86
  async function compileFromFile(config, input) {
82
87
  const definition = input.definition ? await (0, definition_1.loadDefinitionInput)(input.definition) : undefined;
88
+ if (definition && input.templateVars?.DEFINITION_HASH !== undefined) {
89
+ throw new errors_1.ValidationError("DEFINITION_HASH must not be provided explicitly when definition metadata is supplied", { code: "DEFINITION_HASH_OVERRIDE_FORBIDDEN" });
90
+ }
91
+ if (definition && input.templateVars?.DEFINITION_ID !== undefined) {
92
+ throw new errors_1.ValidationError("DEFINITION_ID must not be provided explicitly when definition metadata is supplied", { code: "DEFINITION_ID_OVERRIDE_FORBIDDEN" });
93
+ }
83
94
  const rawSource = await (0, promises_1.readFile)(input.simfPath, "utf8");
95
+ let onChainAnchor;
96
+ if (input.definition?.anchorMode === "on-chain-constant-committed") {
97
+ const detection = (0, definition_1.detectOnChainDefinitionAnchor)(rawSource);
98
+ if (!rawSource.includes("{{DEFINITION_HASH}}")) {
99
+ 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" });
100
+ }
101
+ if (!detection.sourceVerified || !detection.helper) {
102
+ const code = detection.reason?.includes("called")
103
+ ? "DEFINITION_ONCHAIN_HELPER_NOT_CALLED"
104
+ : "DEFINITION_ONCHAIN_HELPER_MISSING";
105
+ 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 });
106
+ }
107
+ onChainAnchor = {
108
+ helper: detection.helper,
109
+ templateVar: "DEFINITION_HASH",
110
+ sourceVerified: true,
111
+ };
112
+ }
84
113
  const templateVars = {
85
114
  ...(input.templateVars ?? {}),
86
115
  ...(definition && input.templateVars?.DEFINITION_HASH === undefined ? { DEFINITION_HASH: definition.hash } : {}),
@@ -96,7 +125,13 @@ async function compileFromFile(config, input) {
96
125
  sourceMode: "file",
97
126
  sourceSimfPath: input.simfPath,
98
127
  templateVars,
99
- definition,
128
+ definition: definition
129
+ ? {
130
+ ...definition,
131
+ anchorMode: input.definition?.anchorMode ?? "artifact-hash-anchor",
132
+ onChainAnchor,
133
+ }
134
+ : undefined,
100
135
  });
101
136
  if (input.artifactPath) {
102
137
  await (0, artifact_1.saveArtifact)(input.artifactPath, artifact);
@@ -105,7 +140,16 @@ async function compileFromFile(config, input) {
105
140
  }
106
141
  async function compileFromPreset(config, input) {
107
142
  const preset = (0, presets_1.getPresetOrThrow)(input.preset);
143
+ if (input.definition?.anchorMode === "on-chain-constant-committed") {
144
+ 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 });
145
+ }
108
146
  const definition = input.definition ? await (0, definition_1.loadDefinitionInput)(input.definition) : undefined;
147
+ if (definition && input.params.DEFINITION_HASH !== undefined) {
148
+ throw new errors_1.ValidationError("DEFINITION_HASH must not be provided explicitly when definition metadata is supplied", { code: "DEFINITION_HASH_OVERRIDE_FORBIDDEN" });
149
+ }
150
+ if (definition && input.params.DEFINITION_ID !== undefined) {
151
+ throw new errors_1.ValidationError("DEFINITION_ID must not be provided explicitly when definition metadata is supplied", { code: "DEFINITION_ID_OVERRIDE_FORBIDDEN" });
152
+ }
109
153
  const params = {
110
154
  ...(0, presets_1.validatePresetParams)(preset, input.params),
111
155
  ...(definition && input.params.DEFINITION_HASH === undefined ? { DEFINITION_HASH: definition.hash } : {}),
@@ -123,7 +167,12 @@ async function compileFromPreset(config, input) {
123
167
  sourceSimfPath: preset.simfTemplatePath,
124
168
  preset: preset.id,
125
169
  templateVars: params,
126
- definition,
170
+ definition: definition
171
+ ? {
172
+ ...definition,
173
+ anchorMode: input.definition?.anchorMode ?? "artifact-hash-anchor",
174
+ }
175
+ : undefined,
127
176
  });
128
177
  if (input.artifactPath) {
129
178
  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 buildArtifactDefinitionMetadata(definition: DefinitionDescriptor): ArtifactDefinitionMetadata;
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;
@@ -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 buildArtifactDefinitionMetadata(definition) {
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
- return verifyDefinitionDescriptorAgainstArtifact(definition, input.artifact.definition, input.expectedType, input.expectedId);
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
  }
@@ -211,6 +211,7 @@ 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,
214
215
  },
215
216
  contract: {
216
217
  address: meta.contractAddress,
@@ -302,6 +303,7 @@ async function buildExecutionState(config, artifact, input) {
302
303
  definitionId: artifact.definition?.definitionId,
303
304
  definitionHash: artifact.definition?.hash,
304
305
  definitionTrustMode: artifact.definition?.trustMode,
306
+ definitionAnchorMode: artifact.definition?.anchorMode,
305
307
  expectedLiquidReceiver: input.expectedLiquidReceiver ?? recipientAddress,
306
308
  contractAddress: artifact.compiled.contractAddress,
307
309
  cmr: artifact.compiled.cmr,
@@ -457,6 +459,7 @@ async function executeGaslessContractCall(config, artifact, input) {
457
459
  definitionId: artifact.definition?.definitionId,
458
460
  definitionHash: artifact.definition?.hash,
459
461
  definitionTrustMode: artifact.definition?.trustMode,
462
+ definitionAnchorMode: artifact.definition?.anchorMode,
460
463
  contractAddress: artifact.compiled.contractAddress,
461
464
  cmr: artifact.compiled.cmr,
462
465
  internalKey: artifact.compiled.internalKey,
@@ -648,6 +651,7 @@ async function executeRelayedGaslessContractCall(config, artifact, input, relaye
648
651
  id: artifact.definition?.definitionId ?? null,
649
652
  hash: artifact.definition?.hash ?? null,
650
653
  trustMode: artifact.definition?.trustMode ?? null,
654
+ anchorMode: artifact.definition?.anchorMode ?? null,
651
655
  },
652
656
  contract: {
653
657
  address: request.detailedSummary.contract.contractAddress,
@@ -1,6 +1,7 @@
1
1
  export type NetworkName = "liquidtestnet" | "liquidv1" | "regtest";
2
2
  export type UtxoPolicy = "smallest_over" | "largest" | "newest";
3
3
  export type DefinitionTrustMode = "hash-anchor";
4
+ export type DefinitionAnchorMode = "artifact-hash-anchor" | "on-chain-constant-committed";
4
5
  export interface RpcConfig {
5
6
  url: string;
6
7
  username: string;
@@ -97,6 +98,7 @@ export interface DefinitionInput {
97
98
  schemaVersion?: string;
98
99
  jsonPath?: string;
99
100
  value?: unknown;
101
+ anchorMode?: DefinitionAnchorMode;
100
102
  }
101
103
  export interface DefinitionDescriptor {
102
104
  definitionType: string;
@@ -112,6 +114,12 @@ export interface ArtifactDefinitionMetadata {
112
114
  schemaVersion: string;
113
115
  hash: string;
114
116
  trustMode: DefinitionTrustMode;
117
+ anchorMode: DefinitionAnchorMode;
118
+ onChainAnchor?: {
119
+ helper: "nonzero-eq_256";
120
+ templateVar: "DEFINITION_HASH";
121
+ sourceVerified: boolean;
122
+ };
115
123
  }
116
124
  export interface DeploymentInfo {
117
125
  contractAddress: string;
@@ -182,6 +190,7 @@ export interface PsetSummary {
182
190
  id: string | null;
183
191
  hash: string | null;
184
192
  trustMode: DefinitionTrustMode | null;
193
+ anchorMode: DefinitionAnchorMode | null;
185
194
  };
186
195
  contract: {
187
196
  address: string;
@@ -255,6 +264,12 @@ export interface DefinitionVerificationResult {
255
264
  reason?: string;
256
265
  definition: DefinitionDescriptor;
257
266
  artifactDefinition?: ArtifactDefinitionMetadata;
267
+ trust: {
268
+ artifactMatch: boolean;
269
+ onChainAnchorPresent: boolean;
270
+ onChainAnchorVerified: boolean;
271
+ effectiveMode: "none" | DefinitionAnchorMode;
272
+ };
258
273
  }
259
274
  export interface WaitForFundingInput {
260
275
  minAmountSat?: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hazbase/simplicity",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "An SDK for Simplicity on Liquid",
5
5
  "author": "IndieSquare Inc <info@hazbase.com>",
6
6
  "keywords": [