@easy1staking/cip113-sdk-ts 0.3.0 → 0.4.0
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 +20 -0
- package/blueprints/standard/v0.3.0/UPSTREAM_PIN.json +30 -0
- package/blueprints/standard/v0.5.0-alpha.2/UPSTREAM_PIN.json +33 -0
- package/blueprints/standard/v0.5.0-alpha.2/plutus.json +1010 -0
- package/blueprints/substandards/dummy/v0.1.0/UPSTREAM_PIN.json +29 -0
- package/blueprints/substandards/dummy/v0.2.0/UPSTREAM_PIN.json +36 -0
- package/blueprints/substandards/dummy/v0.2.0/plutus.json +84 -0
- package/blueprints/substandards/freeze-and-seize/v0.1.0/UPSTREAM_PIN.json +35 -0
- package/dist/core/cip171.d.ts +149 -0
- package/dist/core/cip171.d.ts.map +1 -0
- package/dist/core/cip171.js +284 -0
- package/dist/core/cip171.js.map +1 -0
- package/dist/core/evo-utils.d.ts +125 -17
- package/dist/core/evo-utils.d.ts.map +1 -1
- package/dist/core/evo-utils.js +149 -21
- package/dist/core/evo-utils.js.map +1 -1
- package/dist/core/ledger-order.d.ts +109 -0
- package/dist/core/ledger-order.d.ts.map +1 -0
- package/dist/core/ledger-order.js +185 -0
- package/dist/core/ledger-order.js.map +1 -0
- package/dist/core/registry.d.ts +16 -3
- package/dist/core/registry.d.ts.map +1 -1
- package/dist/core/registry.js +18 -9
- package/dist/core/registry.js.map +1 -1
- package/dist/index.d.ts +27 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +55 -17
- package/dist/index.js.map +1 -1
- package/dist/standard/blueprint.d.ts +48 -1
- package/dist/standard/blueprint.d.ts.map +1 -1
- package/dist/standard/blueprint.js +71 -5
- package/dist/standard/blueprint.js.map +1 -1
- package/dist/standard/scripts.d.ts +76 -27
- package/dist/standard/scripts.d.ts.map +1 -1
- package/dist/standard/scripts.js +177 -49
- package/dist/standard/scripts.js.map +1 -1
- package/dist/substandards/dummy/index.d.ts.map +1 -1
- package/dist/substandards/dummy/index.js +443 -26
- package/dist/substandards/dummy/index.js.map +1 -1
- package/dist/substandards/freeze-and-seize/index.d.ts.map +1 -1
- package/dist/substandards/freeze-and-seize/index.js +283 -41
- package/dist/substandards/freeze-and-seize/index.js.map +1 -1
- package/dist/substandards/interface.d.ts +93 -1
- package/dist/substandards/interface.d.ts.map +1 -1
- package/dist/types.d.ts +87 -4
- package/dist/types.d.ts.map +1 -1
- package/package.json +4 -1
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"artifact": "plutus.json",
|
|
3
|
+
"sha256": "42d95e768b991c3dd9fa09e4fd320bb7650a1564d841502248d5623c88e53fa4",
|
|
4
|
+
"declares": {
|
|
5
|
+
"title": "wsc-poc/aiken-policy",
|
|
6
|
+
"description": "Aiken contracts for project 'wsc-poc/aiken-policy'",
|
|
7
|
+
"version": "0.0.0",
|
|
8
|
+
"compiler": "Aiken v1.1.19+e525483",
|
|
9
|
+
"validators": 4
|
|
10
|
+
},
|
|
11
|
+
"upstream": {
|
|
12
|
+
"repo": null,
|
|
13
|
+
"commit": null,
|
|
14
|
+
"note": "Source project not recorded anywhere in this repo. Unrelated to both the standard blueprint's project and the freeze-and-seize one."
|
|
15
|
+
},
|
|
16
|
+
"blueprint_reproduced": false,
|
|
17
|
+
"provenance": "UNKNOWN",
|
|
18
|
+
"verified": {
|
|
19
|
+
"date": "2026-08-14",
|
|
20
|
+
"findings": [
|
|
21
|
+
"The directory name v0.1.0 is an invented label: the artifact declares version 0.0.0.",
|
|
22
|
+
"Built with Aiken v1.1.19+e525483 - OLDER than every other blueprint in this repo. Three bundled blueprints, three source projects, two compiler versions."
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
"reproduce": {
|
|
26
|
+
"requires": "Aiken v1.1.19+e525483",
|
|
27
|
+
"note": "Cannot be reproduced without locating the source project first."
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"artifact": "plutus.json",
|
|
3
|
+
"sha256": "c75e41f6ff3f71c278ac4765741ea6cf1e222fa24d5601d85e5e3a25bb15ed0f",
|
|
4
|
+
"declares": {
|
|
5
|
+
"title": "wsc-poc/aiken-policy",
|
|
6
|
+
"description": "Aiken contracts for project 'wsc-poc/aiken-policy'",
|
|
7
|
+
"version": "0.0.0",
|
|
8
|
+
"compiler": "Aiken v1.1.21+42babe5",
|
|
9
|
+
"validators": 6
|
|
10
|
+
},
|
|
11
|
+
"upstream": {
|
|
12
|
+
"repo": "https://github.com/cardano-foundation/cip113-programmable-tokens-platform",
|
|
13
|
+
"path": "src/substandards/dummy",
|
|
14
|
+
"commit": "013c11544839754d462e0603de59f4bbf1769479",
|
|
15
|
+
"note": "SOURCE LOCATED. The v0.1.0 pin recorded repo: null / provenance: UNKNOWN because nobody had recorded where this came from. It is the `dummy` substandard in cardano-foundation/cip113-programmable-tokens-platform. The blueprint's own preamble still says 'wsc-poc/aiken-policy' — that is the aiken.toml project name inside that directory, not a separate repository, which is precisely why it looked orphaned."
|
|
16
|
+
},
|
|
17
|
+
"blueprint_reproduced": true,
|
|
18
|
+
"provenance": "UNVERIFIED",
|
|
19
|
+
"reproduce": {
|
|
20
|
+
"requires": "Aiken v1.1.21+42babe5",
|
|
21
|
+
"command": "cd src/substandards/dummy && aiken build",
|
|
22
|
+
"note": "aiken.toml pins v1.1.21. ⚠ aiken BUILDS ANYWAY on a mismatched compiler, emitting only a warning — a blueprint built on the wrong toolchain is indistinguishable from a correct one by inspection. Check the preamble's compiler field, do not trust the environment."
|
|
23
|
+
},
|
|
24
|
+
"verified": {
|
|
25
|
+
"date": "2026-08-25",
|
|
26
|
+
"method": "BUILT FROM LOCATED SOURCE",
|
|
27
|
+
"findings": [
|
|
28
|
+
"OBSERVED: adds `transfer.issue.publish` and `transfer.transfer.publish`, which v0.1.0 lacked entirely. Without them the stake credentials of these two withdraw-0 validators CANNOT BE REGISTERED (a Conway RegCert runs the script under the PUBLISH purpose and falls through to `else`), so the substandard could not register, mint or transfer at all under CIP-113 0.5.x.",
|
|
29
|
+
"OBSERVED: byte-identical across two clean rebuilds with the pinned compiler.",
|
|
30
|
+
"⚠ PROVENANCE IS UNVERIFIED, NOT VERIFIED, AND THE DISTINCTION IS THE POINT. The named commit 013c115 exists ONLY IN A LOCAL CLONE on this workstation. It has not been pushed, reviewed or merged, so no third party can reproduce this artifact from the recorded commit. It becomes VERIFIED when that commit is pushed and the hash re-confirmed against the public repo — not before.",
|
|
31
|
+
"The publish handlers permit REGISTRATION ONLY (RegisterCredential -> True, everything else -> False). Deregistration is refused deliberately: an unregistered credential cannot be withdrawn against, so a permissive publish handler would let any third party disable every token governed by this substandard. Same shape as upstream's core validators.",
|
|
32
|
+
"v0.1.0 is retained alongside, unchanged. It is the artifact this SDK shipped and its provenance record is part of the history; it is also now known non-functional against 0.5.x.",
|
|
33
|
+
"For the record, v0.1.0 did NOT match this source project's own committed blueprint either: v0.1.0 is sha256 42d95e76… built with Aiken v1.1.19, while the platform repo's committed copy at 61374e3 is sha256 6574d840… built with v1.1.21. The SDK was shipping an artifact older than the source project's own."
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
{
|
|
2
|
+
"preamble": {
|
|
3
|
+
"title": "wsc-poc/aiken-policy",
|
|
4
|
+
"description": "Aiken contracts for project 'wsc-poc/aiken-policy'",
|
|
5
|
+
"version": "0.0.0",
|
|
6
|
+
"plutusVersion": "v3",
|
|
7
|
+
"compiler": {
|
|
8
|
+
"name": "Aiken",
|
|
9
|
+
"version": "v1.1.21+42babe5"
|
|
10
|
+
},
|
|
11
|
+
"license": "Apache-2.0"
|
|
12
|
+
},
|
|
13
|
+
"validators": [
|
|
14
|
+
{
|
|
15
|
+
"title": "transfer.issue.withdraw",
|
|
16
|
+
"redeemer": {
|
|
17
|
+
"title": "redeemer",
|
|
18
|
+
"schema": {
|
|
19
|
+
"$ref": "#/definitions/Int"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"compiledCode": "588901010029800aba2aba1aab9eaab9dab9a488889660026464646644b30013370e900200144c8cdc39bad300a0054832004c024c020dd5001c56600266e1d2006002899192cc004cdc3a400060126ea8c02cc03000a294629410081bad300a0013008375400714a0803100618029baa00130070033006300700130060013003375400d149a26cac80081",
|
|
23
|
+
"hash": "4be2c6d3f5c5e66f45d20801c0d55341f0ae3b939187c9591ec29028"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"title": "transfer.issue.publish",
|
|
27
|
+
"redeemer": {
|
|
28
|
+
"title": "_r",
|
|
29
|
+
"schema": {
|
|
30
|
+
"$ref": "#/definitions/Data"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"compiledCode": "588901010029800aba2aba1aab9eaab9dab9a488889660026464646644b30013370e900200144c8cdc39bad300a0054832004c024c020dd5001c56600266e1d2006002899192cc004cdc3a400060126ea8c02cc03000a294629410081bad300a0013008375400714a0803100618029baa00130070033006300700130060013003375400d149a26cac80081",
|
|
34
|
+
"hash": "4be2c6d3f5c5e66f45d20801c0d55341f0ae3b939187c9591ec29028"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"title": "transfer.issue.else",
|
|
38
|
+
"redeemer": {
|
|
39
|
+
"schema": {}
|
|
40
|
+
},
|
|
41
|
+
"compiledCode": "588901010029800aba2aba1aab9eaab9dab9a488889660026464646644b30013370e900200144c8cdc39bad300a0054832004c024c020dd5001c56600266e1d2006002899192cc004cdc3a400060126ea8c02cc03000a294629410081bad300a0013008375400714a0803100618029baa00130070033006300700130060013003375400d149a26cac80081",
|
|
42
|
+
"hash": "4be2c6d3f5c5e66f45d20801c0d55341f0ae3b939187c9591ec29028"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"title": "transfer.transfer.withdraw",
|
|
46
|
+
"redeemer": {
|
|
47
|
+
"title": "redeemer",
|
|
48
|
+
"schema": {
|
|
49
|
+
"$ref": "#/definitions/Int"
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"compiledCode": "588901010029800aba2aba1aab9eaab9dab9a488889660026464646644b30013370e900200144c8cdc39bad300a005482400cc024c020dd5001c56600266e1d2006002899192cc004cdc3a400060126ea8c02cc03000a294629410081bad300a0013008375400714a0803100618029baa00130070033006300700130060013003375400d149a26cac80081",
|
|
53
|
+
"hash": "6ae51f97696717eb0de100c151a30965a3c4ff97c167124b2b206ba9"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"title": "transfer.transfer.publish",
|
|
57
|
+
"redeemer": {
|
|
58
|
+
"title": "_r",
|
|
59
|
+
"schema": {
|
|
60
|
+
"$ref": "#/definitions/Data"
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"compiledCode": "588901010029800aba2aba1aab9eaab9dab9a488889660026464646644b30013370e900200144c8cdc39bad300a005482400cc024c020dd5001c56600266e1d2006002899192cc004cdc3a400060126ea8c02cc03000a294629410081bad300a0013008375400714a0803100618029baa00130070033006300700130060013003375400d149a26cac80081",
|
|
64
|
+
"hash": "6ae51f97696717eb0de100c151a30965a3c4ff97c167124b2b206ba9"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"title": "transfer.transfer.else",
|
|
68
|
+
"redeemer": {
|
|
69
|
+
"schema": {}
|
|
70
|
+
},
|
|
71
|
+
"compiledCode": "588901010029800aba2aba1aab9eaab9dab9a488889660026464646644b30013370e900200144c8cdc39bad300a005482400cc024c020dd5001c56600266e1d2006002899192cc004cdc3a400060126ea8c02cc03000a294629410081bad300a0013008375400714a0803100618029baa00130070033006300700130060013003375400d149a26cac80081",
|
|
72
|
+
"hash": "6ae51f97696717eb0de100c151a30965a3c4ff97c167124b2b206ba9"
|
|
73
|
+
}
|
|
74
|
+
],
|
|
75
|
+
"definitions": {
|
|
76
|
+
"Data": {
|
|
77
|
+
"title": "Data",
|
|
78
|
+
"description": "Any Plutus data."
|
|
79
|
+
},
|
|
80
|
+
"Int": {
|
|
81
|
+
"dataType": "integer"
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"artifact": "plutus.json",
|
|
3
|
+
"sha256": "9514852e32ad2181595b6c8e65349ce5636cb3a11d0acd2e47dec55ca9f21c8f",
|
|
4
|
+
"declares": {
|
|
5
|
+
"title": "cip113/freeze-unfreeze",
|
|
6
|
+
"description": "CIP113 Sub Standard for freeze/unfreeze capabilities",
|
|
7
|
+
"version": "0.0.0",
|
|
8
|
+
"compiler": "Aiken v1.1.21+42babe5",
|
|
9
|
+
"validators": 10
|
|
10
|
+
},
|
|
11
|
+
"upstream": {
|
|
12
|
+
"repo": "https://github.com/cardano-foundation/cip113-programmable-tokens-platform",
|
|
13
|
+
"path": "src/substandards/freeze-and-seize",
|
|
14
|
+
"commit": "013c11544839754d462e0603de59f4bbf1769479",
|
|
15
|
+
"note": "SOURCE LOCATED. The previous pin recorded repo: null / provenance: UNKNOWN because nobody had written it down — it is the `freeze-and-seize` substandard in the platform repo, alongside `dummy`. The preamble title 'cip113/freeze-unfreeze' is that directory's aiken.toml project name, not a separate repository."
|
|
16
|
+
},
|
|
17
|
+
"blueprint_reproduced": true,
|
|
18
|
+
"provenance": "VERIFIED",
|
|
19
|
+
"reproduce": {
|
|
20
|
+
"requires": "Aiken v1.1.21+42babe5",
|
|
21
|
+
"command": "cd src/substandards/freeze-and-seize && aiken build",
|
|
22
|
+
"note": "aiken.toml pins compiler v1.1.21 and stdlib v3.0.0. ⚠ aiken BUILDS ANYWAY on a mismatched compiler, emitting only a warning — an artifact built on the wrong toolchain is indistinguishable from a correct one by inspection. Assert the compiler from THIS FILE'S `declares.compiler` and the artifact's own `preamble.compiler`, never from the shell you happen to be in."
|
|
23
|
+
},
|
|
24
|
+
"verified": {
|
|
25
|
+
"date": "2026-08-25",
|
|
26
|
+
"method": "REPRODUCED FROM SOURCE",
|
|
27
|
+
"findings": [
|
|
28
|
+
"OBSERVED: `aiken build` at platform commit 013c1154, with Aiken v1.1.21+42babe5 and stdlib v3.0.0, reproduces this artifact EXACTLY — sha256 9514852e32ad2181595b6c8e65349ce5636cb3a11d0acd2e47dec55ca9f21c8f. Byte-identical across two clean rebuilds, and byte-identical to the copy committed in the platform repo.",
|
|
29
|
+
"NO DIVERGENCE between the committed artifact and its source. That was the outcome worth checking for: a divergence would have meant the committed blueprint and the code it claims to come from disagree — the silent-corruption channel a shared, mutable toolchain creates.",
|
|
30
|
+
"The machine-global Aiken was on v1.1.9 when this was rebuilt. It was borrowed to v1.1.21 (the version aiken.toml pins) for the build and RESTORED to v1.1.9 immediately after; the platform repo was left clean.",
|
|
31
|
+
"This blueprint already carries `publish` handlers on both of its withdraw-0 validators (example_transfer_logic.issuer_admin_contract and .transfer), so — unlike the dummy substandard — it has no registration blocker under CIP-113 0.5.x. Its obstacles are entirely off-chain.",
|
|
32
|
+
"⚠ PROVENANCE IS VERIFIED FOR THE ARTIFACT, NOT AN ENDORSEMENT OF THE CODE. This blueprint is still written against 0.3.x semantics on the off-chain side: `freeze-and-seize` is quarantined (PLAN.md D-14) and refuses to initialise. Reproducibility says the bytes come from the named source; it says nothing about whether they are correct for the current protocol."
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CIP-171 — On-chain Smart Contract Bytecode Verification.
|
|
3
|
+
*
|
|
4
|
+
* Builds the transaction metadata payload (label 1984) that links one or more
|
|
5
|
+
* deployed script hashes back to a source repository + commit, so verifiers can
|
|
6
|
+
* reproduce the on-chain script hashes by re-compiling the source.
|
|
7
|
+
*
|
|
8
|
+
* Wire format per the CIP and the uplc-link reference impl:
|
|
9
|
+
*
|
|
10
|
+
* { 1984: [ <chunk1>, <chunk2>, ..., <chunkN> ] } ; each chunk ≤ 64 bytes
|
|
11
|
+
*
|
|
12
|
+
* Concatenated chunks decode to a single CBOR PlutusData, in the **six-field**
|
|
13
|
+
* layout — NOT the five-field one in the currently published CIP text:
|
|
14
|
+
*
|
|
15
|
+
* Constr <compilerId>
|
|
16
|
+
* [ 0: sourceUrl : ByteArray (UTF-8)
|
|
17
|
+
* , 1: commitHash : ByteArray (20 or 32 RAW bytes, not UTF-8)
|
|
18
|
+
* , 2: sourcePath : ByteArray (UTF-8, "" for repo root)
|
|
19
|
+
* , 3: compilerVersion : ByteArray (UTF-8)
|
|
20
|
+
* , 4: env : ByteArray (UTF-8, "" = built without --env)
|
|
21
|
+
* , 5: parameters : Map<ScriptHash(28b), List<ByteString>>
|
|
22
|
+
* ]
|
|
23
|
+
*
|
|
24
|
+
* The six-field layout redefines constructor 0 IN PLACE. This matters more than
|
|
25
|
+
* a version bump would: the reference registry (uplc-link) parses strictly on
|
|
26
|
+
* `fields.size() == 6` and **drops anything else, log-only, by design**. A
|
|
27
|
+
* five-field record is therefore not rejected loudly — it is silently ignored.
|
|
28
|
+
* Encoder and decoder here are both strict on 6 for that reason.
|
|
29
|
+
*
|
|
30
|
+
* Byte-level compatibility is asserted against uplc-link's own cross-language
|
|
31
|
+
* fixture (their FE `metadata-encoding.test.ts` / BE `SerdeTest`), which anchors
|
|
32
|
+
* the TypeScript and Java implementations to the same bytes. See
|
|
33
|
+
* CIP171_CBOR_OPTIONS: the encoding is indefinite-length arrays with a
|
|
34
|
+
* DEFINITE-length, key-sorted map, which is not Evolution's default.
|
|
35
|
+
*
|
|
36
|
+
* The `parameters` map keys are the **un-parameterised** (raw) script hashes —
|
|
37
|
+
* i.e. Aiken's `validators[].hash` straight out of plutus.json. Each value is a
|
|
38
|
+
* list of **byte strings**, each wrapping the CBOR encoding of one parameter,
|
|
39
|
+
* which applied to the raw script via `applyParamsToScript` reproduce the
|
|
40
|
+
* deployed hash.
|
|
41
|
+
*
|
|
42
|
+
* The published CDDL says `parameter_list = [ * plutus_data ]` — inline. That is
|
|
43
|
+
* wrong against the reference, and wrong in the worst way: an inline record
|
|
44
|
+
* still parses and still shows six fields, but the registry reads `.bytes` on
|
|
45
|
+
* each element, gets empty strings, and stores a record with its parameters
|
|
46
|
+
* silently gone. Hence `Cip171ScriptEntry.params` is typed `HexString[]`, so the
|
|
47
|
+
* mistake is unrepresentable rather than merely documented.
|
|
48
|
+
*
|
|
49
|
+
* Limitation: each raw script can appear at most once in `parameters`. Deploying
|
|
50
|
+
* the same raw script twice with different params (e.g. two `always_fail`
|
|
51
|
+
* instances with distinct nonces) cannot be fully described in a single record.
|
|
52
|
+
*/
|
|
53
|
+
import type { HexString, ScriptHash, PlutusData } from "../types.js";
|
|
54
|
+
/** CIP-10 metadata label registered for CIP-171. */
|
|
55
|
+
export declare const CIP171_METADATA_LABEL = 1984n;
|
|
56
|
+
/** Maximum size of any single metadata bytestring (Cardano protocol limit). */
|
|
57
|
+
export declare const CIP171_MAX_CHUNK_BYTES = 64;
|
|
58
|
+
/**
|
|
59
|
+
* PlutusData constructor IDs identifying the compiler + schema version.
|
|
60
|
+
* Sourced from the CIP-0171 README. Constructor 0 is Aiken (schema v1).
|
|
61
|
+
*/
|
|
62
|
+
export declare const CompilerType: {
|
|
63
|
+
readonly AIKEN: 0;
|
|
64
|
+
readonly PLUTARCH: 1;
|
|
65
|
+
readonly PLUTUS_TX: 2;
|
|
66
|
+
readonly SCALUS: 3;
|
|
67
|
+
readonly PLU_TS: 4;
|
|
68
|
+
readonly OPSHIN: 5;
|
|
69
|
+
};
|
|
70
|
+
export type CompilerType = (typeof CompilerType)[keyof typeof CompilerType];
|
|
71
|
+
/** One entry in the CIP-171 parameters map. */
|
|
72
|
+
export interface Cip171ScriptEntry {
|
|
73
|
+
/** 28-byte hex Blake2b-224 hash of the **un-parameterised** compiled script. */
|
|
74
|
+
rawScriptHash: ScriptHash;
|
|
75
|
+
/**
|
|
76
|
+
* Arguments applied to that raw script to produce the deployed hash, each as
|
|
77
|
+
* an **opaque byte string in hex** — NOT inline PlutusData.
|
|
78
|
+
*
|
|
79
|
+
* The published CDDL says `parameter_list = [ * plutus_data ]`, and it is
|
|
80
|
+
* wrong. The reference wire shape is `[ * bytes ]`: every element is a
|
|
81
|
+
* bytestring whose content is the parameter's CBOR encoding. Emitting inline
|
|
82
|
+
* PlutusData is not rejected by the registry — its parser reads `.bytes` on
|
|
83
|
+
* each element, gets an empty string, and stores a record whose parameters
|
|
84
|
+
* have silently vanished while the record itself still parses.
|
|
85
|
+
*
|
|
86
|
+
* The type is `string[]` rather than `PlutusData[]` precisely so that mistake
|
|
87
|
+
* cannot be made: use {@link cip171Param} to serialize PlutusData.
|
|
88
|
+
*/
|
|
89
|
+
params: HexString[];
|
|
90
|
+
}
|
|
91
|
+
export interface Cip171Record {
|
|
92
|
+
compilerType: CompilerType;
|
|
93
|
+
/** Git-clone-compatible repo URL. */
|
|
94
|
+
sourceUrl: string;
|
|
95
|
+
/** Raw git commit hash hex (40 chars for SHA-1, 64 for SHA-256). */
|
|
96
|
+
commitHash: HexString;
|
|
97
|
+
/** Path inside the repo. Empty string for root. */
|
|
98
|
+
sourcePath?: string;
|
|
99
|
+
/** Exact compiler version string (e.g. "v1.1.21+42babe5"). */
|
|
100
|
+
compilerVersion: string;
|
|
101
|
+
/**
|
|
102
|
+
* Build environment — the value passed to the compiler's `--env` flag.
|
|
103
|
+
* Empty string (the default) means the script was built without `--env`;
|
|
104
|
+
* PlutusData has no null, so absence is encoded as empty bytes.
|
|
105
|
+
*
|
|
106
|
+
* Field index 4 of the six-field layout. See the note on the layout below.
|
|
107
|
+
*/
|
|
108
|
+
env?: string;
|
|
109
|
+
/** Map keyed by raw script hash. */
|
|
110
|
+
scripts: Cip171ScriptEntry[];
|
|
111
|
+
}
|
|
112
|
+
export declare function buildCip171PlutusData(record: Cip171Record): PlutusData;
|
|
113
|
+
/**
|
|
114
|
+
* CBOR options reproducing the reference registry's bytes exactly:
|
|
115
|
+
* indefinite-length arrays/lists (`9f…ff`) with a DEFINITE-length map (`a2`).
|
|
116
|
+
*
|
|
117
|
+
* Evolution's default (`CML_DATA_DEFAULT_OPTIONS`) uses indefinite maps (`bf`),
|
|
118
|
+
* which does not match. Verified byte-identical against uplc-link's
|
|
119
|
+
* cross-language fixture — see test/cip171.test.mjs.
|
|
120
|
+
*/
|
|
121
|
+
export declare const CIP171_CBOR_OPTIONS: {
|
|
122
|
+
readonly mode: "custom";
|
|
123
|
+
readonly useIndefiniteArrays: true;
|
|
124
|
+
readonly useIndefiniteMaps: false;
|
|
125
|
+
readonly useDefiniteForEmpty: true;
|
|
126
|
+
readonly sortMapKeys: true;
|
|
127
|
+
readonly useMinimalEncoding: true;
|
|
128
|
+
};
|
|
129
|
+
/**
|
|
130
|
+
* Encode a CIP-171 record to the chunked metadatum value (a list of byte
|
|
131
|
+
* chunks ≤ 64 bytes each). Drop the result straight into Evolution's
|
|
132
|
+
* `attachMetadata({ label: CIP171_METADATA_LABEL, metadata: chunks })`.
|
|
133
|
+
*/
|
|
134
|
+
export declare function buildCip171Metadatum(record: Cip171Record, chunkSize?: number): Uint8Array[];
|
|
135
|
+
/** Slice a byte array into ≤ chunkSize pieces in order. */
|
|
136
|
+
export declare function chunkBytes(bytes: Uint8Array, chunkSize: number): Uint8Array[];
|
|
137
|
+
/** Reassemble a chunked metadatum and decode the embedded CIP-171 record. */
|
|
138
|
+
export declare function decodeCip171Metadatum(chunks: ReadonlyArray<Uint8Array>): Cip171Record;
|
|
139
|
+
export declare function decodeCip171PlutusData(data: PlutusData): Cip171Record;
|
|
140
|
+
/**
|
|
141
|
+
* Serialize a PlutusData parameter to the hex byte string a CIP-171 record
|
|
142
|
+
* expects, using the encoding the reference registry reproduces.
|
|
143
|
+
*
|
|
144
|
+
* A verifier applies these to the un-parameterised script via
|
|
145
|
+
* `applyParamsToScript` and compares the resulting hash, so the bytes must be
|
|
146
|
+
* exactly what the original build applied.
|
|
147
|
+
*/
|
|
148
|
+
export declare function cip171Param(data: PlutusData): HexString;
|
|
149
|
+
//# sourceMappingURL=cip171.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cip171.d.ts","sourceRoot":"","sources":["../../src/core/cip171.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAMrE,oDAAoD;AACpD,eAAO,MAAM,qBAAqB,QAAQ,CAAC;AAE3C,+EAA+E;AAC/E,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAEzC;;;GAGG;AACH,eAAO,MAAM,YAAY;;;;;;;CAOf,CAAC;AACX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC;AAM5E,+CAA+C;AAC/C,MAAM,WAAW,iBAAiB;IAChC,gFAAgF;IAChF,aAAa,EAAE,UAAU,CAAC;IAC1B;;;;;;;;;;;;;OAaG;IACH,MAAM,EAAE,SAAS,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,YAAY,CAAC;IAC3B,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,UAAU,EAAE,SAAS,CAAC;IACtB,mDAAmD;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8DAA8D;IAC9D,eAAe,EAAE,MAAM,CAAC;IACxB;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,OAAO,EAAE,iBAAiB,EAAE,CAAC;CAC9B;AAqED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,YAAY,GAAG,UAAU,CAuCtE;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB;;;;;;;CAOtB,CAAC;AAEX;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,YAAY,EACpB,SAAS,GAAE,MAA+B,GACzC,UAAU,EAAE,CAMd;AAED,2DAA2D;AAC3D,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,GAAG,UAAU,EAAE,CAO7E;AAMD,6EAA6E;AAC7E,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,CAAC,UAAU,CAAC,GAAG,YAAY,CAUrF;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,UAAU,GAAG,YAAY,CAoCrE;AAwBD;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,SAAS,CAEvD"}
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CIP-171 — On-chain Smart Contract Bytecode Verification.
|
|
3
|
+
*
|
|
4
|
+
* Builds the transaction metadata payload (label 1984) that links one or more
|
|
5
|
+
* deployed script hashes back to a source repository + commit, so verifiers can
|
|
6
|
+
* reproduce the on-chain script hashes by re-compiling the source.
|
|
7
|
+
*
|
|
8
|
+
* Wire format per the CIP and the uplc-link reference impl:
|
|
9
|
+
*
|
|
10
|
+
* { 1984: [ <chunk1>, <chunk2>, ..., <chunkN> ] } ; each chunk ≤ 64 bytes
|
|
11
|
+
*
|
|
12
|
+
* Concatenated chunks decode to a single CBOR PlutusData, in the **six-field**
|
|
13
|
+
* layout — NOT the five-field one in the currently published CIP text:
|
|
14
|
+
*
|
|
15
|
+
* Constr <compilerId>
|
|
16
|
+
* [ 0: sourceUrl : ByteArray (UTF-8)
|
|
17
|
+
* , 1: commitHash : ByteArray (20 or 32 RAW bytes, not UTF-8)
|
|
18
|
+
* , 2: sourcePath : ByteArray (UTF-8, "" for repo root)
|
|
19
|
+
* , 3: compilerVersion : ByteArray (UTF-8)
|
|
20
|
+
* , 4: env : ByteArray (UTF-8, "" = built without --env)
|
|
21
|
+
* , 5: parameters : Map<ScriptHash(28b), List<ByteString>>
|
|
22
|
+
* ]
|
|
23
|
+
*
|
|
24
|
+
* The six-field layout redefines constructor 0 IN PLACE. This matters more than
|
|
25
|
+
* a version bump would: the reference registry (uplc-link) parses strictly on
|
|
26
|
+
* `fields.size() == 6` and **drops anything else, log-only, by design**. A
|
|
27
|
+
* five-field record is therefore not rejected loudly — it is silently ignored.
|
|
28
|
+
* Encoder and decoder here are both strict on 6 for that reason.
|
|
29
|
+
*
|
|
30
|
+
* Byte-level compatibility is asserted against uplc-link's own cross-language
|
|
31
|
+
* fixture (their FE `metadata-encoding.test.ts` / BE `SerdeTest`), which anchors
|
|
32
|
+
* the TypeScript and Java implementations to the same bytes. See
|
|
33
|
+
* CIP171_CBOR_OPTIONS: the encoding is indefinite-length arrays with a
|
|
34
|
+
* DEFINITE-length, key-sorted map, which is not Evolution's default.
|
|
35
|
+
*
|
|
36
|
+
* The `parameters` map keys are the **un-parameterised** (raw) script hashes —
|
|
37
|
+
* i.e. Aiken's `validators[].hash` straight out of plutus.json. Each value is a
|
|
38
|
+
* list of **byte strings**, each wrapping the CBOR encoding of one parameter,
|
|
39
|
+
* which applied to the raw script via `applyParamsToScript` reproduce the
|
|
40
|
+
* deployed hash.
|
|
41
|
+
*
|
|
42
|
+
* The published CDDL says `parameter_list = [ * plutus_data ]` — inline. That is
|
|
43
|
+
* wrong against the reference, and wrong in the worst way: an inline record
|
|
44
|
+
* still parses and still shows six fields, but the registry reads `.bytes` on
|
|
45
|
+
* each element, gets empty strings, and stores a record with its parameters
|
|
46
|
+
* silently gone. Hence `Cip171ScriptEntry.params` is typed `HexString[]`, so the
|
|
47
|
+
* mistake is unrepresentable rather than merely documented.
|
|
48
|
+
*
|
|
49
|
+
* Limitation: each raw script can appear at most once in `parameters`. Deploying
|
|
50
|
+
* the same raw script twice with different params (e.g. two `always_fail`
|
|
51
|
+
* instances with distinct nonces) cannot be fully described in a single record.
|
|
52
|
+
*/
|
|
53
|
+
import { Data, Bytes } from "@evolution-sdk/evolution";
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
// Constants
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
/** CIP-10 metadata label registered for CIP-171. */
|
|
58
|
+
export const CIP171_METADATA_LABEL = 1984n;
|
|
59
|
+
/** Maximum size of any single metadata bytestring (Cardano protocol limit). */
|
|
60
|
+
export const CIP171_MAX_CHUNK_BYTES = 64;
|
|
61
|
+
/**
|
|
62
|
+
* PlutusData constructor IDs identifying the compiler + schema version.
|
|
63
|
+
* Sourced from the CIP-0171 README. Constructor 0 is Aiken (schema v1).
|
|
64
|
+
*/
|
|
65
|
+
export const CompilerType = {
|
|
66
|
+
AIKEN: 0,
|
|
67
|
+
PLUTARCH: 1,
|
|
68
|
+
PLUTUS_TX: 2,
|
|
69
|
+
SCALUS: 3,
|
|
70
|
+
PLU_TS: 4,
|
|
71
|
+
OPSHIN: 5,
|
|
72
|
+
};
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
// Encoding
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
/**
|
|
77
|
+
* Build the CIP-171 PlutusData record (the structure stored under metadata 1984
|
|
78
|
+
* once chunks are reassembled and decoded).
|
|
79
|
+
*/
|
|
80
|
+
/** Hex string of exactly `bytes` bytes, case-insensitive. */
|
|
81
|
+
function isHexOfBytes(s, ...bytes) {
|
|
82
|
+
return typeof s === "string" && bytes.some((b) => new RegExp(`^[0-9a-fA-F]{${b * 2}}$`).test(s));
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Validate a record before it is encoded.
|
|
86
|
+
*
|
|
87
|
+
* A CIP-171 record is a PERMANENT, PUBLIC claim that a set of deployed scripts
|
|
88
|
+
* was produced from a named repository at a named commit. It goes on chain in
|
|
89
|
+
* transaction metadata and cannot be retracted. A malformed or placeholder
|
|
90
|
+
* commit hash therefore does not fail loudly at some later point — it becomes
|
|
91
|
+
* an immutable false provenance record that verifiers will try, and fail, to
|
|
92
|
+
* reproduce.
|
|
93
|
+
*
|
|
94
|
+
* This cannot detect a well-formed but WRONG commit. It does stop the realistic
|
|
95
|
+
* accidents: a null, empty, truncated or placeholder value reaching the chain
|
|
96
|
+
* because the blueprint's provenance was never actually established.
|
|
97
|
+
*/
|
|
98
|
+
function validateCip171Record(record) {
|
|
99
|
+
if (!isHexOfBytes(record.commitHash, 20, 32)) {
|
|
100
|
+
throw new Error(`CIP-171: commitHash must be a 20- or 32-byte hex string (40 or 64 hex chars), got ` +
|
|
101
|
+
`${record.commitHash === undefined ? "undefined" : JSON.stringify(record.commitHash)}. ` +
|
|
102
|
+
`This record is a permanent on-chain claim about where the deployed scripts came from — ` +
|
|
103
|
+
`do not emit one until the blueprint's provenance is actually known.`);
|
|
104
|
+
}
|
|
105
|
+
if (typeof record.sourceUrl !== "string" || record.sourceUrl.trim() === "") {
|
|
106
|
+
throw new Error("CIP-171: sourceUrl must be a non-empty repository URL");
|
|
107
|
+
}
|
|
108
|
+
if (typeof record.compilerVersion !== "string" || record.compilerVersion.trim() === "") {
|
|
109
|
+
throw new Error("CIP-171: compilerVersion must be non-empty — verifiers reproduce hashes with this exact compiler");
|
|
110
|
+
}
|
|
111
|
+
if (record.scripts.length === 0) {
|
|
112
|
+
throw new Error("CIP-171: a record with no scripts claims nothing; refusing to encode it");
|
|
113
|
+
}
|
|
114
|
+
for (const e of record.scripts) {
|
|
115
|
+
for (const p of e.params) {
|
|
116
|
+
if (typeof p !== "string" || !/^([0-9a-fA-F]{2})*$/.test(p) || p.length === 0) {
|
|
117
|
+
throw new Error(`CIP-171: parameters must be non-empty hex byte strings, got ${JSON.stringify(p)} ` +
|
|
118
|
+
`for ${e.rawScriptHash}. Serialize PlutusData with cip171Param() — inline PlutusData ` +
|
|
119
|
+
`is silently dropped by the reference registry.`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (!isHexOfBytes(e.rawScriptHash, 28)) {
|
|
123
|
+
throw new Error(`CIP-171: rawScriptHash must be a 28-byte hex string (56 hex chars), got ` +
|
|
124
|
+
`${JSON.stringify(e.rawScriptHash)}. These are the UN-parameterised hashes from ` +
|
|
125
|
+
`plutus.json, not the deployed ones.`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
export function buildCip171PlutusData(record) {
|
|
130
|
+
validateCip171Record(record);
|
|
131
|
+
const seen = new Set();
|
|
132
|
+
const entries = [];
|
|
133
|
+
for (const e of record.scripts) {
|
|
134
|
+
const k = e.rawScriptHash.toLowerCase();
|
|
135
|
+
if (seen.has(k)) {
|
|
136
|
+
throw new Error(`CIP-171: duplicate raw script hash ${k}. Each raw script may appear at most once.`);
|
|
137
|
+
}
|
|
138
|
+
seen.add(k);
|
|
139
|
+
entries.push([
|
|
140
|
+
Data.bytearray(e.rawScriptHash),
|
|
141
|
+
// Each param wrapped as a BYTESTRING. Inline PlutusData here is the
|
|
142
|
+
// published-CDDL reading and it corrupts silently — see Cip171ScriptEntry.
|
|
143
|
+
Data.list(e.params.map((p) => Data.bytearray(p))),
|
|
144
|
+
]);
|
|
145
|
+
}
|
|
146
|
+
// Canonical map ordering: ascending by key bytes. The reference registry's
|
|
147
|
+
// fixtures are byte-sorted, and Evolution's `sortMapKeys` codec option does
|
|
148
|
+
// not reach Data maps, so the sort is done here rather than delegated.
|
|
149
|
+
entries.sort((a, b) => {
|
|
150
|
+
const ka = a[0], kb = b[0];
|
|
151
|
+
const n = Math.min(ka.length, kb.length);
|
|
152
|
+
for (let i = 0; i < n; i++)
|
|
153
|
+
if (ka[i] !== kb[i])
|
|
154
|
+
return ka[i] - kb[i];
|
|
155
|
+
return ka.length - kb.length;
|
|
156
|
+
});
|
|
157
|
+
return Data.constr(BigInt(record.compilerType), [
|
|
158
|
+
Data.bytearray(utf8ToHex(record.sourceUrl)),
|
|
159
|
+
Data.bytearray(record.commitHash),
|
|
160
|
+
Data.bytearray(utf8ToHex(record.sourcePath ?? "")),
|
|
161
|
+
Data.bytearray(utf8ToHex(record.compilerVersion)),
|
|
162
|
+
Data.bytearray(utf8ToHex(record.env ?? "")),
|
|
163
|
+
Data.map(entries),
|
|
164
|
+
]);
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* CBOR options reproducing the reference registry's bytes exactly:
|
|
168
|
+
* indefinite-length arrays/lists (`9f…ff`) with a DEFINITE-length map (`a2`).
|
|
169
|
+
*
|
|
170
|
+
* Evolution's default (`CML_DATA_DEFAULT_OPTIONS`) uses indefinite maps (`bf`),
|
|
171
|
+
* which does not match. Verified byte-identical against uplc-link's
|
|
172
|
+
* cross-language fixture — see test/cip171.test.mjs.
|
|
173
|
+
*/
|
|
174
|
+
export const CIP171_CBOR_OPTIONS = {
|
|
175
|
+
mode: "custom",
|
|
176
|
+
useIndefiniteArrays: true,
|
|
177
|
+
useIndefiniteMaps: false,
|
|
178
|
+
useDefiniteForEmpty: true,
|
|
179
|
+
sortMapKeys: true,
|
|
180
|
+
useMinimalEncoding: true,
|
|
181
|
+
};
|
|
182
|
+
/**
|
|
183
|
+
* Encode a CIP-171 record to the chunked metadatum value (a list of byte
|
|
184
|
+
* chunks ≤ 64 bytes each). Drop the result straight into Evolution's
|
|
185
|
+
* `attachMetadata({ label: CIP171_METADATA_LABEL, metadata: chunks })`.
|
|
186
|
+
*/
|
|
187
|
+
export function buildCip171Metadatum(record, chunkSize = CIP171_MAX_CHUNK_BYTES) {
|
|
188
|
+
if (chunkSize < 1 || chunkSize > CIP171_MAX_CHUNK_BYTES) {
|
|
189
|
+
throw new Error(`CIP-171: chunk size must be in [1, ${CIP171_MAX_CHUNK_BYTES}]`);
|
|
190
|
+
}
|
|
191
|
+
const cbor = Data.toCBORBytes(buildCip171PlutusData(record), CIP171_CBOR_OPTIONS);
|
|
192
|
+
return chunkBytes(cbor, chunkSize);
|
|
193
|
+
}
|
|
194
|
+
/** Slice a byte array into ≤ chunkSize pieces in order. */
|
|
195
|
+
export function chunkBytes(bytes, chunkSize) {
|
|
196
|
+
const chunks = [];
|
|
197
|
+
for (let i = 0; i < bytes.length; i += chunkSize) {
|
|
198
|
+
chunks.push(bytes.slice(i, Math.min(i + chunkSize, bytes.length)));
|
|
199
|
+
}
|
|
200
|
+
if (chunks.length === 0)
|
|
201
|
+
chunks.push(new Uint8Array(0));
|
|
202
|
+
return chunks;
|
|
203
|
+
}
|
|
204
|
+
// ---------------------------------------------------------------------------
|
|
205
|
+
// Decoding (round-trip helper for tests & verifiers)
|
|
206
|
+
// ---------------------------------------------------------------------------
|
|
207
|
+
/** Reassemble a chunked metadatum and decode the embedded CIP-171 record. */
|
|
208
|
+
export function decodeCip171Metadatum(chunks) {
|
|
209
|
+
const total = chunks.reduce((n, c) => n + c.length, 0);
|
|
210
|
+
const merged = new Uint8Array(total);
|
|
211
|
+
let off = 0;
|
|
212
|
+
for (const c of chunks) {
|
|
213
|
+
merged.set(c, off);
|
|
214
|
+
off += c.length;
|
|
215
|
+
}
|
|
216
|
+
const data = Data.fromCBORBytes(merged);
|
|
217
|
+
return decodeCip171PlutusData(data);
|
|
218
|
+
}
|
|
219
|
+
export function decodeCip171PlutusData(data) {
|
|
220
|
+
if (!(data instanceof Data.Constr)) {
|
|
221
|
+
throw new Error("CIP-171: expected Constr at top level");
|
|
222
|
+
}
|
|
223
|
+
const compilerType = Number(data.index);
|
|
224
|
+
const fields = data.fields;
|
|
225
|
+
// STRICT six fields. The reference registry drops anything else (log-only,
|
|
226
|
+
// by design), so a five-field record is unparseable there rather than
|
|
227
|
+
// partially understood. Failing loudly here beats emitting one.
|
|
228
|
+
if (fields.length !== 6) {
|
|
229
|
+
throw new Error(`CIP-171: expected exactly 6 fields, got ${fields.length}. ` +
|
|
230
|
+
`The five-field layout was redefined in place; records in the old shape are ` +
|
|
231
|
+
`silently dropped by the registry.`);
|
|
232
|
+
}
|
|
233
|
+
const sourceUrl = bytesToUtf8(asBytes(fields[0]));
|
|
234
|
+
const commitHash = Bytes.toHex(asBytes(fields[1]));
|
|
235
|
+
const sourcePath = bytesToUtf8(asBytes(fields[2]));
|
|
236
|
+
const compilerVersion = bytesToUtf8(asBytes(fields[3]));
|
|
237
|
+
const env = bytesToUtf8(asBytes(fields[4]));
|
|
238
|
+
const paramsField = fields[5];
|
|
239
|
+
if (!(paramsField instanceof globalThis.Map)) {
|
|
240
|
+
throw new Error("CIP-171: expected Map for parameters field");
|
|
241
|
+
}
|
|
242
|
+
const scripts = [];
|
|
243
|
+
for (const [k, v] of paramsField.entries()) {
|
|
244
|
+
const rawScriptHash = Bytes.toHex(asBytes(k));
|
|
245
|
+
if (!Array.isArray(v)) {
|
|
246
|
+
throw new Error(`CIP-171: expected List for params of ${rawScriptHash}`);
|
|
247
|
+
}
|
|
248
|
+
// Elements are bytestrings on the wire; surface them as hex, matching the
|
|
249
|
+
// encoder's input shape so a decode/encode round-trip is lossless.
|
|
250
|
+
scripts.push({ rawScriptHash, params: v.map((p) => Bytes.toHex(asBytes(p))) });
|
|
251
|
+
}
|
|
252
|
+
return { compilerType, sourceUrl, commitHash, sourcePath, compilerVersion, env, scripts };
|
|
253
|
+
}
|
|
254
|
+
// ---------------------------------------------------------------------------
|
|
255
|
+
// Internal helpers
|
|
256
|
+
// ---------------------------------------------------------------------------
|
|
257
|
+
function asBytes(d) {
|
|
258
|
+
if (!(d instanceof Uint8Array)) {
|
|
259
|
+
throw new Error("CIP-171: expected ByteArray (Uint8Array)");
|
|
260
|
+
}
|
|
261
|
+
return d;
|
|
262
|
+
}
|
|
263
|
+
function bytesToUtf8(bytes) {
|
|
264
|
+
return bytes.length === 0 ? "" : new TextDecoder().decode(bytes);
|
|
265
|
+
}
|
|
266
|
+
function utf8ToHex(s) {
|
|
267
|
+
const bytes = new TextEncoder().encode(s);
|
|
268
|
+
let out = "";
|
|
269
|
+
for (const b of bytes)
|
|
270
|
+
out += b.toString(16).padStart(2, "0");
|
|
271
|
+
return out;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Serialize a PlutusData parameter to the hex byte string a CIP-171 record
|
|
275
|
+
* expects, using the encoding the reference registry reproduces.
|
|
276
|
+
*
|
|
277
|
+
* A verifier applies these to the un-parameterised script via
|
|
278
|
+
* `applyParamsToScript` and compares the resulting hash, so the bytes must be
|
|
279
|
+
* exactly what the original build applied.
|
|
280
|
+
*/
|
|
281
|
+
export function cip171Param(data) {
|
|
282
|
+
return Data.toCBORHex(data, CIP171_CBOR_OPTIONS);
|
|
283
|
+
}
|
|
284
|
+
//# sourceMappingURL=cip171.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cip171.js","sourceRoot":"","sources":["../../src/core/cip171.ts"],"names":[],"mappings":"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"}
|