@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/README.md
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
# @hazbase/simplicity
|
|
2
|
+
[](https://badge.fury.io/js/@hazbase%2Fsimplicity)
|
|
3
|
+
[](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:
|
|
@@ -123,6 +134,82 @@ simplicity-cli definition verify \
|
|
|
123
134
|
|
|
124
135
|
For a bond-oriented walkthrough, see [docs/definitions/README.md](./docs/definitions/README.md).
|
|
125
136
|
|
|
137
|
+
## Trusted Issuance State JSON
|
|
138
|
+
|
|
139
|
+
The same hash-anchor model now also applies to issuance state documents such as a bond issuance record.
|
|
140
|
+
|
|
141
|
+
This is useful when you want to say not only:
|
|
142
|
+
|
|
143
|
+
- "these are the bond terms,"
|
|
144
|
+
|
|
145
|
+
but also:
|
|
146
|
+
|
|
147
|
+
- "this bond was issued in this amount, with this outstanding principal, under this controller."
|
|
148
|
+
|
|
149
|
+
The SDK now supports:
|
|
150
|
+
|
|
151
|
+
- loading and hashing a state JSON with `sdk.loadStateDocument(...)`,
|
|
152
|
+
- storing its hash in the artifact,
|
|
153
|
+
- committing `STATE_HASH` into custom `.simf` contract logic,
|
|
154
|
+
- verifying later that the issuance state JSON still matches the compiled contract.
|
|
155
|
+
|
|
156
|
+
For Bond issuance, the recommended shape is:
|
|
157
|
+
|
|
158
|
+
```json
|
|
159
|
+
{
|
|
160
|
+
"issuanceId": "BOND-2026-001-ISSUE-1",
|
|
161
|
+
"bondId": "BOND-2026-001",
|
|
162
|
+
"issuerEntityId": "hazbase-treasury",
|
|
163
|
+
"issuedPrincipal": 1000000,
|
|
164
|
+
"outstandingPrincipal": 1000000,
|
|
165
|
+
"redeemedPrincipal": 0,
|
|
166
|
+
"currencyAssetId": "bitcoin",
|
|
167
|
+
"controllerXonly": "<xonly>",
|
|
168
|
+
"issuedAt": "2026-03-10T00:00:00Z",
|
|
169
|
+
"status": "ISSUED"
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Minimal TypeScript flow:
|
|
174
|
+
|
|
175
|
+
```ts
|
|
176
|
+
const compiled = await sdk.bonds.defineBond({
|
|
177
|
+
definitionPath: "./docs/definitions/bond-definition.json",
|
|
178
|
+
issuancePath: "./docs/definitions/bond-issuance-state.json",
|
|
179
|
+
simfPath: "./docs/definitions/bond-issuance-anchor.simf",
|
|
180
|
+
artifactPath: "./bond-issuance.artifact.json",
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
const verification = await sdk.bonds.verifyBond({
|
|
184
|
+
artifactPath: "./bond-issuance.artifact.json",
|
|
185
|
+
definitionPath: "./docs/definitions/bond-definition.json",
|
|
186
|
+
issuancePath: "./docs/definitions/bond-issuance-state.json",
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
console.log(verification.crossChecks.principalInvariantValid);
|
|
190
|
+
console.log(verification.issuance.trust.effectiveMode);
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
CLI equivalents:
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
simplicity-cli state show \
|
|
197
|
+
--type bond-issuance \
|
|
198
|
+
--id BOND-2026-001-ISSUE-1 \
|
|
199
|
+
--json-path ./docs/definitions/bond-issuance-state.json
|
|
200
|
+
|
|
201
|
+
simplicity-cli state verify \
|
|
202
|
+
--artifact ./bond-issuance.artifact.json \
|
|
203
|
+
--type bond-issuance \
|
|
204
|
+
--id BOND-2026-001-ISSUE-1 \
|
|
205
|
+
--json-path ./docs/definitions/bond-issuance-state.json
|
|
206
|
+
|
|
207
|
+
simplicity-cli bond verify \
|
|
208
|
+
--artifact ./bond-issuance.artifact.json \
|
|
209
|
+
--definition-json ./docs/definitions/bond-definition.json \
|
|
210
|
+
--issuance-json ./docs/definitions/bond-issuance-state.json
|
|
211
|
+
```
|
|
212
|
+
|
|
126
213
|
## Install
|
|
127
214
|
|
|
128
215
|
You need three things:
|
|
@@ -800,6 +887,9 @@ These examples are included to help you jump to the right workflow quickly.
|
|
|
800
887
|
- [gasless-transfer.ts](./examples/gasless-transfer.ts): standard relayer-backed gasless L-BTC transfer.
|
|
801
888
|
- [define-bond.ts](./examples/define-bond.ts): compile a bond example with a trusted definition hash anchor.
|
|
802
889
|
- [show-bond-definition.ts](./examples/show-bond-definition.ts): verify and retrieve a trusted bond definition from JSON + artifact.
|
|
890
|
+
- [define-bond-issuance.ts](./examples/define-bond-issuance.ts): compile a bond example with both trusted definition and issuance state anchors.
|
|
891
|
+
- [show-bond-issuance.ts](./examples/show-bond-issuance.ts): load a bond artifact together with its verified issuance state.
|
|
892
|
+
- [verify-bond-issuance.ts](./examples/verify-bond-issuance.ts): run combined Bond definition/state verification and invariant checks.
|
|
803
893
|
|
|
804
894
|
In addition to the in-repo examples, the package has also been validated from a blank external consumer project with:
|
|
805
895
|
- `npm install @hazbase/simplicity`
|
|
@@ -828,9 +918,20 @@ When you compile with `definition: { ... }`, the artifact also carries:
|
|
|
828
918
|
- `schemaVersion`
|
|
829
919
|
- `hash`
|
|
830
920
|
- `trustMode`
|
|
921
|
+
- `anchorMode`
|
|
831
922
|
|
|
832
923
|
That is what allows the SDK and CLI to verify that an off-chain JSON definition still matches the contract you compiled.
|
|
833
924
|
|
|
925
|
+
When you also compile with `state: { ... }`, the artifact can additionally carry:
|
|
926
|
+
- `stateType`
|
|
927
|
+
- `stateId`
|
|
928
|
+
- `schemaVersion`
|
|
929
|
+
- `hash`
|
|
930
|
+
- `trustMode`
|
|
931
|
+
- `anchorMode`
|
|
932
|
+
|
|
933
|
+
That is what allows the SDK and CLI to verify that an off-chain issuance state document still matches the contract you compiled.
|
|
934
|
+
|
|
834
935
|
### When should I use a preset instead of a custom `.simf` file?
|
|
835
936
|
|
|
836
937
|
Use a preset first when you are learning the lifecycle or your use case already matches a built-in contract. Move to custom `.simf` when your business rules are app-specific.
|
package/dist/cli.js
CHANGED
|
@@ -8,6 +8,7 @@ const promises_1 = require("node:fs/promises");
|
|
|
8
8
|
const node_path_1 = __importDefault(require("node:path"));
|
|
9
9
|
const artifact_1 = require("./core/artifact");
|
|
10
10
|
const definition_1 = require("./core/definition");
|
|
11
|
+
const state_1 = require("./core/state");
|
|
11
12
|
const presets_1 = require("./core/presets");
|
|
12
13
|
const errors_1 = require("./core/errors");
|
|
13
14
|
const SimplicityClient_1 = require("./client/SimplicityClient");
|
|
@@ -72,7 +73,8 @@ function parseDefinitionInput() {
|
|
|
72
73
|
const jsonPath = getArg("definition-json");
|
|
73
74
|
const valueJson = getArg("definition-value");
|
|
74
75
|
const schemaVersion = getArg("definition-schema-version");
|
|
75
|
-
|
|
76
|
+
const anchorMode = getArg("definition-anchor-mode");
|
|
77
|
+
if (!type && !id && !jsonPath && !valueJson && !schemaVersion && !anchorMode) {
|
|
76
78
|
return undefined;
|
|
77
79
|
}
|
|
78
80
|
return {
|
|
@@ -81,6 +83,26 @@ function parseDefinitionInput() {
|
|
|
81
83
|
schemaVersion: schemaVersion ?? undefined,
|
|
82
84
|
jsonPath,
|
|
83
85
|
value: valueJson ? JSON.parse(valueJson) : undefined,
|
|
86
|
+
anchorMode,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function parseStateInput() {
|
|
90
|
+
const type = getArg("state-type");
|
|
91
|
+
const id = getArg("state-id");
|
|
92
|
+
const jsonPath = getArg("state-json");
|
|
93
|
+
const valueJson = getArg("state-value");
|
|
94
|
+
const schemaVersion = getArg("state-schema-version");
|
|
95
|
+
const anchorMode = getArg("state-anchor-mode");
|
|
96
|
+
if (!type && !id && !jsonPath && !valueJson && !schemaVersion && !anchorMode) {
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
type: type ?? "",
|
|
101
|
+
id: id ?? "",
|
|
102
|
+
schemaVersion: schemaVersion ?? undefined,
|
|
103
|
+
jsonPath,
|
|
104
|
+
value: valueJson ? JSON.parse(valueJson) : undefined,
|
|
105
|
+
anchorMode,
|
|
84
106
|
};
|
|
85
107
|
}
|
|
86
108
|
function resolveConfig() {
|
|
@@ -382,6 +404,21 @@ function formatArtifactHelp(artifact, preset, utxos) {
|
|
|
382
404
|
` schema version: ${artifact.definition.schemaVersion}`,
|
|
383
405
|
` hash: ${artifact.definition.hash}`,
|
|
384
406
|
` trust mode: ${artifact.definition.trustMode}`,
|
|
407
|
+
` anchor mode: ${artifact.definition.anchorMode}`,
|
|
408
|
+
` on-chain helper: ${artifact.definition.onChainAnchor?.helper ?? "(none)"}`,
|
|
409
|
+
` source verified: ${artifact.definition.onChainAnchor?.sourceVerified === true ? "yes" : "no"}`,
|
|
410
|
+
].join("\n")
|
|
411
|
+
: " (none)";
|
|
412
|
+
const state = artifact.state
|
|
413
|
+
? [
|
|
414
|
+
` type: ${artifact.state.stateType}`,
|
|
415
|
+
` id: ${artifact.state.stateId}`,
|
|
416
|
+
` schema version: ${artifact.state.schemaVersion}`,
|
|
417
|
+
` hash: ${artifact.state.hash}`,
|
|
418
|
+
` trust mode: ${artifact.state.trustMode}`,
|
|
419
|
+
` anchor mode: ${artifact.state.anchorMode}`,
|
|
420
|
+
` on-chain helper: ${artifact.state.onChainAnchor?.helper ?? "(none)"}`,
|
|
421
|
+
` source verified: ${artifact.state.onChainAnchor?.sourceVerified === true ? "yes" : "no"}`,
|
|
385
422
|
].join("\n")
|
|
386
423
|
: " (none)";
|
|
387
424
|
const compileSource = artifact.source.simfPath ?? artifact.legacy?.simfTemplatePath ?? "(unknown)";
|
|
@@ -405,6 +442,9 @@ function formatArtifactHelp(artifact, preset, utxos) {
|
|
|
405
442
|
"Definition Anchor:",
|
|
406
443
|
definition,
|
|
407
444
|
"",
|
|
445
|
+
"State Anchor:",
|
|
446
|
+
state,
|
|
447
|
+
"",
|
|
408
448
|
"Suggested Commands:",
|
|
409
449
|
` ${inspectCommand}`,
|
|
410
450
|
` ${executeCommand}`,
|
|
@@ -446,7 +486,7 @@ async function main() {
|
|
|
446
486
|
const subcommand = process.argv[3];
|
|
447
487
|
const sdk = (0, SimplicityClient_1.createSimplicityClient)(resolveConfig());
|
|
448
488
|
if (!command) {
|
|
449
|
-
throw new Error("Usage: simplicity-cli <compile|presets|preset|contract|artifact|definition|gasless> ...");
|
|
489
|
+
throw new Error("Usage: simplicity-cli <compile|presets|preset|contract|artifact|definition|state|bond|gasless> ...");
|
|
450
490
|
}
|
|
451
491
|
if (command === "compile") {
|
|
452
492
|
const result = await sdk.compileFromFile({
|
|
@@ -454,6 +494,7 @@ async function main() {
|
|
|
454
494
|
templateVars: parseAssignments(getMultiArgs("template-var")),
|
|
455
495
|
artifactPath: getArg("artifact"),
|
|
456
496
|
definition: parseDefinitionInput(),
|
|
497
|
+
state: parseStateInput(),
|
|
457
498
|
});
|
|
458
499
|
printJson({ artifact: result.artifact, deployment: result.deployment() });
|
|
459
500
|
return;
|
|
@@ -466,7 +507,10 @@ async function main() {
|
|
|
466
507
|
value: getArg("value") ? JSON.parse(getArg("value")) : undefined,
|
|
467
508
|
schemaVersion: getArg("schema-version"),
|
|
468
509
|
});
|
|
469
|
-
printJson(
|
|
510
|
+
printJson({
|
|
511
|
+
...definition,
|
|
512
|
+
anchorRecommendation: "Use --definition-anchor-mode on-chain-constant-committed with a blessed custom .simf helper for on-chain enforcement",
|
|
513
|
+
});
|
|
470
514
|
return;
|
|
471
515
|
}
|
|
472
516
|
if (command === "definition" && subcommand === "verify") {
|
|
@@ -485,6 +529,41 @@ async function main() {
|
|
|
485
529
|
reason: verification.reason,
|
|
486
530
|
definition: verification.definition,
|
|
487
531
|
artifactDefinition: verification.artifactDefinition ?? null,
|
|
532
|
+
trust: verification.trust,
|
|
533
|
+
});
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
if (command === "state" && subcommand === "show") {
|
|
537
|
+
const state = await (0, state_1.loadStateInput)({
|
|
538
|
+
type: requireArg("type"),
|
|
539
|
+
id: requireArg("id"),
|
|
540
|
+
jsonPath: getArg("json-path"),
|
|
541
|
+
value: getArg("value") ? JSON.parse(getArg("value")) : undefined,
|
|
542
|
+
schemaVersion: getArg("schema-version"),
|
|
543
|
+
});
|
|
544
|
+
printJson({
|
|
545
|
+
...state,
|
|
546
|
+
anchorRecommendation: "Use --state-anchor-mode on-chain-constant-committed with a blessed custom .simf helper for on-chain enforcement",
|
|
547
|
+
});
|
|
548
|
+
return;
|
|
549
|
+
}
|
|
550
|
+
if (command === "state" && subcommand === "verify") {
|
|
551
|
+
const verification = await sdk.verifyStateAgainstArtifact({
|
|
552
|
+
artifactPath: requireArg("artifact"),
|
|
553
|
+
type: getArg("type"),
|
|
554
|
+
id: getArg("id"),
|
|
555
|
+
expectedType: getArg("expected-type"),
|
|
556
|
+
expectedId: getArg("expected-id"),
|
|
557
|
+
jsonPath: getArg("json-path"),
|
|
558
|
+
value: getArg("value") ? JSON.parse(getArg("value")) : undefined,
|
|
559
|
+
schemaVersion: getArg("schema-version"),
|
|
560
|
+
});
|
|
561
|
+
printJson({
|
|
562
|
+
verified: verification.ok,
|
|
563
|
+
reason: verification.reason,
|
|
564
|
+
state: verification.state,
|
|
565
|
+
artifactState: verification.artifactState ?? null,
|
|
566
|
+
trust: verification.trust,
|
|
488
567
|
});
|
|
489
568
|
return;
|
|
490
569
|
}
|
|
@@ -534,6 +613,7 @@ async function main() {
|
|
|
534
613
|
params,
|
|
535
614
|
artifactPath: getArg("artifact"),
|
|
536
615
|
definition: parseDefinitionInput(),
|
|
616
|
+
state: parseStateInput(),
|
|
537
617
|
});
|
|
538
618
|
printJson({ artifact: result.artifact, deployment: result.deployment() });
|
|
539
619
|
return;
|
|
@@ -563,6 +643,25 @@ async function main() {
|
|
|
563
643
|
});
|
|
564
644
|
return;
|
|
565
645
|
}
|
|
646
|
+
if (command === "bond" && subcommand === "define") {
|
|
647
|
+
const result = await sdk.bonds.defineBond({
|
|
648
|
+
definitionPath: getArg("definition-json"),
|
|
649
|
+
issuancePath: getArg("issuance-json"),
|
|
650
|
+
simfPath: getArg("simf"),
|
|
651
|
+
artifactPath: getArg("artifact"),
|
|
652
|
+
});
|
|
653
|
+
printJson({ artifact: result.artifact, deployment: result.deployment() });
|
|
654
|
+
return;
|
|
655
|
+
}
|
|
656
|
+
if (command === "bond" && subcommand === "verify") {
|
|
657
|
+
const result = await sdk.bonds.verifyBond({
|
|
658
|
+
artifactPath: requireArg("artifact"),
|
|
659
|
+
definitionPath: getArg("definition-json"),
|
|
660
|
+
issuancePath: getArg("issuance-json"),
|
|
661
|
+
});
|
|
662
|
+
printJson(result);
|
|
663
|
+
return;
|
|
664
|
+
}
|
|
566
665
|
if (command === "contract" && subcommand === "wait-funding") {
|
|
567
666
|
const compiled = await sdk.loadArtifact(requireArg("artifact"));
|
|
568
667
|
const utxos = await compiled.at().waitForFunding({
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ArtifactDefinitionMetadata, DeploymentInfo, SimplicityArtifact, SimplicityClientConfig } from "../core/types";
|
|
1
|
+
import { ArtifactDefinitionMetadata, ArtifactStateMetadata, DeploymentInfo, SimplicityArtifact, SimplicityClientConfig } from "../core/types";
|
|
2
2
|
import { DeployedContract } from "./DeployedContract";
|
|
3
3
|
export declare class CompiledContract {
|
|
4
4
|
private readonly config;
|
|
@@ -8,6 +8,7 @@ export declare class CompiledContract {
|
|
|
8
8
|
get cmr(): string;
|
|
9
9
|
get program(): string;
|
|
10
10
|
definition(): ArtifactDefinitionMetadata | null;
|
|
11
|
+
state(): ArtifactStateMetadata | null;
|
|
11
12
|
deployment(): DeploymentInfo;
|
|
12
13
|
saveArtifact(path: string): Promise<void>;
|
|
13
14
|
at(addressOverride?: string): DeployedContract;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { verifyDefinitionAgainstArtifact } from "../core/definition";
|
|
2
|
-
import {
|
|
2
|
+
import { verifyStateAgainstArtifact } from "../core/state";
|
|
3
|
+
import { ArtifactDefinitionMetadata, ArtifactStateMetadata, ContractUtxo, ExecuteCallInput, ExecuteResult, GaslessExecuteInput, GaslessExecuteResult, InspectCallInput, InspectResult, SimplicityArtifact, SimplicityClientConfig, WaitForFundingInput } from "../core/types";
|
|
3
4
|
export declare class DeployedContract {
|
|
4
5
|
private readonly config;
|
|
5
6
|
readonly artifact: SimplicityArtifact;
|
|
@@ -21,5 +22,19 @@ export declare class DeployedContract {
|
|
|
21
22
|
definition: Awaited<ReturnType<typeof verifyDefinitionAgainstArtifact>>["definition"];
|
|
22
23
|
artifactDefinition: ArtifactDefinitionMetadata | null;
|
|
23
24
|
reason?: string;
|
|
25
|
+
trust: Awaited<ReturnType<typeof verifyDefinitionAgainstArtifact>>["trust"];
|
|
26
|
+
}>;
|
|
27
|
+
getTrustedState(input: {
|
|
28
|
+
jsonPath?: string;
|
|
29
|
+
value?: unknown;
|
|
30
|
+
type?: string;
|
|
31
|
+
id?: string;
|
|
32
|
+
schemaVersion?: string;
|
|
33
|
+
}): Promise<{
|
|
34
|
+
verified: boolean;
|
|
35
|
+
state: Awaited<ReturnType<typeof verifyStateAgainstArtifact>>["state"];
|
|
36
|
+
artifactState: ArtifactStateMetadata | null;
|
|
37
|
+
reason?: string;
|
|
38
|
+
trust: Awaited<ReturnType<typeof verifyStateAgainstArtifact>>["trust"];
|
|
24
39
|
}>;
|
|
25
40
|
}
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.DeployedContract = void 0;
|
|
4
4
|
const executor_1 = require("../core/executor");
|
|
5
5
|
const definition_1 = require("../core/definition");
|
|
6
|
+
const state_1 = require("../core/state");
|
|
6
7
|
const executor_2 = require("../core/executor");
|
|
7
8
|
class DeployedContract {
|
|
8
9
|
config;
|
|
@@ -58,6 +59,28 @@ class DeployedContract {
|
|
|
58
59
|
definition: verification.definition,
|
|
59
60
|
artifactDefinition: verification.artifactDefinition ?? null,
|
|
60
61
|
reason: verification.reason,
|
|
62
|
+
trust: verification.trust,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
async getTrustedState(input) {
|
|
66
|
+
const verification = await (0, state_1.verifyStateAgainstArtifact)({
|
|
67
|
+
artifact: this.artifact,
|
|
68
|
+
state: {
|
|
69
|
+
type: input.type ?? this.artifact.state?.stateType ?? "",
|
|
70
|
+
id: input.id ?? this.artifact.state?.stateId ?? "",
|
|
71
|
+
schemaVersion: input.schemaVersion,
|
|
72
|
+
jsonPath: input.jsonPath,
|
|
73
|
+
value: input.value,
|
|
74
|
+
},
|
|
75
|
+
expectedType: this.artifact.state?.stateType,
|
|
76
|
+
expectedId: this.artifact.state?.stateId,
|
|
77
|
+
});
|
|
78
|
+
return {
|
|
79
|
+
verified: verification.ok,
|
|
80
|
+
state: verification.state,
|
|
81
|
+
artifactState: verification.artifactState ?? null,
|
|
82
|
+
reason: verification.reason,
|
|
83
|
+
trust: verification.trust,
|
|
61
84
|
};
|
|
62
85
|
}
|
|
63
86
|
}
|
|
@@ -1,21 +1,48 @@
|
|
|
1
1
|
import { ElementsRpcClient } from "../core/rpc";
|
|
2
|
-
import { DefinitionInput, DefinitionVerificationResult, CompileFromFileInput, CompileFromPresetInput, DefinitionDescriptor, SimplicityArtifact, SimplicityClientConfig } from "../core/types";
|
|
2
|
+
import { BondDefinition, BondIssuanceState, DefinitionInput, DefinitionVerificationResult, CompileFromFileInput, CompileFromPresetInput, DefinitionDescriptor, StateDocumentDescriptor, StateDocumentInput, StateVerificationResult, SimplicityArtifact, SimplicityClientConfig } from "../core/types";
|
|
3
3
|
import { RelayerClient } from "../gasless/RelayerClient";
|
|
4
4
|
import { GaslessTransferInput, GaslessTransferResult, RelayerClientConfig } from "../gasless/types";
|
|
5
5
|
import { CompiledContract } from "./ContractFactory";
|
|
6
6
|
import { DeployedContract } from "./DeployedContract";
|
|
7
|
+
import { loadBond, verifyBond } from "../domain/bond";
|
|
7
8
|
export declare class SimplicityClient {
|
|
8
9
|
readonly config: SimplicityClientConfig;
|
|
9
10
|
readonly rpc: ElementsRpcClient;
|
|
10
11
|
readonly payments: {
|
|
11
12
|
gaslessTransfer: (input: GaslessTransferInput) => Promise<GaslessTransferResult>;
|
|
12
13
|
};
|
|
14
|
+
readonly bonds: {
|
|
15
|
+
defineBond: (input: {
|
|
16
|
+
definitionPath?: string;
|
|
17
|
+
definitionValue?: BondDefinition;
|
|
18
|
+
issuancePath?: string;
|
|
19
|
+
issuanceValue?: BondIssuanceState;
|
|
20
|
+
simfPath?: string;
|
|
21
|
+
artifactPath?: string;
|
|
22
|
+
}) => Promise<CompiledContract>;
|
|
23
|
+
verifyBond: (input: {
|
|
24
|
+
artifactPath?: string;
|
|
25
|
+
artifact?: SimplicityArtifact;
|
|
26
|
+
definitionPath?: string;
|
|
27
|
+
definitionValue?: BondDefinition;
|
|
28
|
+
issuancePath?: string;
|
|
29
|
+
issuanceValue?: BondIssuanceState;
|
|
30
|
+
}) => ReturnType<typeof verifyBond>;
|
|
31
|
+
loadBond: (input: {
|
|
32
|
+
artifactPath: string;
|
|
33
|
+
definitionPath?: string;
|
|
34
|
+
definitionValue?: BondDefinition;
|
|
35
|
+
issuancePath?: string;
|
|
36
|
+
issuanceValue?: BondIssuanceState;
|
|
37
|
+
}) => ReturnType<typeof loadBond>;
|
|
38
|
+
};
|
|
13
39
|
constructor(config: SimplicityClientConfig);
|
|
14
40
|
compileFromFile(input: CompileFromFileInput): Promise<CompiledContract>;
|
|
15
41
|
compileFromPreset(input: CompileFromPresetInput): Promise<CompiledContract>;
|
|
16
42
|
loadArtifact(path: string): Promise<CompiledContract>;
|
|
17
43
|
define(input: DefinitionInput): Promise<DefinitionDescriptor>;
|
|
18
44
|
loadDefinition(input: DefinitionInput): Promise<DefinitionDescriptor>;
|
|
45
|
+
loadStateDocument(input: StateDocumentInput): Promise<StateDocumentDescriptor>;
|
|
19
46
|
verifyDefinitionAgainstArtifact(input: {
|
|
20
47
|
artifactPath?: string;
|
|
21
48
|
artifact?: SimplicityArtifact;
|
|
@@ -27,6 +54,17 @@ export declare class SimplicityClient {
|
|
|
27
54
|
id?: string;
|
|
28
55
|
schemaVersion?: string;
|
|
29
56
|
}): Promise<DefinitionVerificationResult>;
|
|
57
|
+
verifyStateAgainstArtifact(input: {
|
|
58
|
+
artifactPath?: string;
|
|
59
|
+
artifact?: SimplicityArtifact;
|
|
60
|
+
jsonPath?: string;
|
|
61
|
+
value?: unknown;
|
|
62
|
+
expectedType?: string;
|
|
63
|
+
expectedId?: string;
|
|
64
|
+
type?: string;
|
|
65
|
+
id?: string;
|
|
66
|
+
schemaVersion?: string;
|
|
67
|
+
}): Promise<StateVerificationResult>;
|
|
30
68
|
fromArtifact(artifact: SimplicityArtifact): DeployedContract;
|
|
31
69
|
relayer(config: RelayerClientConfig): RelayerClient;
|
|
32
70
|
private gaslessTransfer;
|
|
@@ -5,21 +5,29 @@ exports.createSimplicityClient = createSimplicityClient;
|
|
|
5
5
|
const artifact_1 = require("../core/artifact");
|
|
6
6
|
const compiler_1 = require("../core/compiler");
|
|
7
7
|
const definition_1 = require("../core/definition");
|
|
8
|
+
const state_1 = require("../core/state");
|
|
8
9
|
const errors_1 = require("../core/errors");
|
|
9
10
|
const rpc_1 = require("../core/rpc");
|
|
10
11
|
const RelayerClient_1 = require("../gasless/RelayerClient");
|
|
11
12
|
const ContractFactory_1 = require("./ContractFactory");
|
|
12
13
|
const DeployedContract_1 = require("./DeployedContract");
|
|
14
|
+
const bond_1 = require("../domain/bond");
|
|
13
15
|
class SimplicityClient {
|
|
14
16
|
config;
|
|
15
17
|
rpc;
|
|
16
18
|
payments;
|
|
19
|
+
bonds;
|
|
17
20
|
constructor(config) {
|
|
18
21
|
this.config = config;
|
|
19
22
|
this.rpc = new rpc_1.ElementsRpcClient(config.rpc);
|
|
20
23
|
this.payments = {
|
|
21
24
|
gaslessTransfer: async (input) => this.gaslessTransfer(input),
|
|
22
25
|
};
|
|
26
|
+
this.bonds = {
|
|
27
|
+
defineBond: async (input) => (0, bond_1.defineBond)(this, input),
|
|
28
|
+
verifyBond: async (input) => (0, bond_1.verifyBond)(this, input),
|
|
29
|
+
loadBond: async (input) => (0, bond_1.loadBond)(this, input),
|
|
30
|
+
};
|
|
23
31
|
}
|
|
24
32
|
async compileFromFile(input) {
|
|
25
33
|
const artifact = await (0, compiler_1.compileFromFile)(this.config, input);
|
|
@@ -39,6 +47,9 @@ class SimplicityClient {
|
|
|
39
47
|
async loadDefinition(input) {
|
|
40
48
|
return (0, definition_1.loadDefinitionInput)(input);
|
|
41
49
|
}
|
|
50
|
+
async loadStateDocument(input) {
|
|
51
|
+
return (0, state_1.loadStateInput)(input);
|
|
52
|
+
}
|
|
42
53
|
async verifyDefinitionAgainstArtifact(input) {
|
|
43
54
|
const artifact = input.artifact ?? (input.artifactPath ? await (0, artifact_1.loadArtifact)(input.artifactPath, this.config.network) : undefined);
|
|
44
55
|
if (!artifact) {
|
|
@@ -57,6 +68,24 @@ class SimplicityClient {
|
|
|
57
68
|
expectedId: input.expectedId,
|
|
58
69
|
});
|
|
59
70
|
}
|
|
71
|
+
async verifyStateAgainstArtifact(input) {
|
|
72
|
+
const artifact = input.artifact ?? (input.artifactPath ? await (0, artifact_1.loadArtifact)(input.artifactPath, this.config.network) : undefined);
|
|
73
|
+
if (!artifact) {
|
|
74
|
+
throw new errors_1.ValidationError("artifactPath or artifact is required");
|
|
75
|
+
}
|
|
76
|
+
return (0, state_1.verifyStateAgainstArtifact)({
|
|
77
|
+
artifact,
|
|
78
|
+
state: {
|
|
79
|
+
type: input.type ?? input.expectedType ?? artifact.state?.stateType ?? "",
|
|
80
|
+
id: input.id ?? input.expectedId ?? artifact.state?.stateId ?? "",
|
|
81
|
+
schemaVersion: input.schemaVersion,
|
|
82
|
+
jsonPath: input.jsonPath,
|
|
83
|
+
value: input.value,
|
|
84
|
+
},
|
|
85
|
+
expectedType: input.expectedType,
|
|
86
|
+
expectedId: input.expectedId,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
60
89
|
fromArtifact(artifact) {
|
|
61
90
|
return new DeployedContract_1.DeployedContract(this.config, artifact);
|
|
62
91
|
}
|
package/dist/core/artifact.js
CHANGED
|
@@ -17,7 +17,22 @@ function isArtifactV5(value) {
|
|
|
17
17
|
}
|
|
18
18
|
function normalizeArtifact(artifact, networkDefault = "liquidtestnet") {
|
|
19
19
|
if (artifact.version === exports.SDK_ARTIFACT_VERSION) {
|
|
20
|
-
|
|
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
|
+
state: current.state
|
|
30
|
+
? {
|
|
31
|
+
...current.state,
|
|
32
|
+
anchorMode: current.state.anchorMode ?? "artifact-hash-anchor",
|
|
33
|
+
}
|
|
34
|
+
: undefined,
|
|
35
|
+
};
|
|
21
36
|
}
|
|
22
37
|
if (!isArtifactV5(artifact)) {
|
|
23
38
|
throw new errors_1.ArtifactError("Unsupported artifact version", artifact);
|
|
@@ -56,6 +71,7 @@ function normalizeArtifact(artifact, networkDefault = "liquidtestnet") {
|
|
|
56
71
|
notes: null,
|
|
57
72
|
},
|
|
58
73
|
definition: undefined,
|
|
74
|
+
state: undefined,
|
|
59
75
|
legacy: {
|
|
60
76
|
simfTemplatePath: artifact.simfTemplatePath,
|
|
61
77
|
params: artifact.params,
|
|
@@ -92,6 +108,7 @@ async function loadArtifact(artifactPath, networkDefault = "liquidtestnet") {
|
|
|
92
108
|
}
|
|
93
109
|
: undefined,
|
|
94
110
|
definition: normalized.definition,
|
|
111
|
+
state: normalized.state,
|
|
95
112
|
};
|
|
96
113
|
}
|
|
97
114
|
async function saveArtifact(artifactPath, artifact) {
|