|
| 1 | +# LS-IDL Registry Profile |
| 2 | + |
| 3 | +**Status**: CellScript 0.24 protocol and tooling contract |
| 4 | + |
| 5 | +**Profile schema**: `cellscript-registry-ls-idl-interface-v1` |
| 6 | + |
| 7 | +**LS-IDL format version**: `0.1` |
| 8 | + |
| 9 | +This profile lets the CellScript Artifact Registry publish and resolve an |
| 10 | +LS-IDL witness interface for a deployed CKB Lock Script. It preserves the |
| 11 | +upstream commitment rule exactly: |
| 12 | + |
| 13 | +```text |
| 14 | +code Cell data = executable bytes || SHA-256(raw idl.json bytes) |
| 15 | +``` |
| 16 | + |
| 17 | +The Registry stores the original IDL object bytes in the immutable release |
| 18 | +bundle. It never parses and reserialises those bytes on the read path. |
| 19 | + |
| 20 | +## What The Profile Proves |
| 21 | + |
| 22 | +An accepted profile proves all of the following: |
| 23 | + |
| 24 | +- the ABI object is valid JSON within the Registry's size and field budgets; |
| 25 | +- the document uses the supported LS-IDL 0.1 schema and witness types; |
| 26 | +- the declared digest equals `SHA-256` of the exact ABI object bytes; |
| 27 | +- the executable object's final 32 bytes equal that digest; |
| 28 | +- the package is a deployable `ckb_executable` with `script_role = "lock"`; |
| 29 | +- a lookup result belongs to an active, public, chain-verified deployment on |
| 30 | + the requested Registry network. |
| 31 | + |
| 32 | +It does **not** prove that the Lock Script decodes witness data as described, |
| 33 | +that every described field is semantically enforced, that a transaction is |
| 34 | +valid, or that the Script is secure. Build verification and security review |
| 35 | +remain separate evidence. |
| 36 | + |
| 37 | +## Artifact Profile Contract |
| 38 | + |
| 39 | +`profile_contract.interface` is accepted only on deployable CKB executables: |
| 40 | + |
| 41 | +```json |
| 42 | +{ |
| 43 | + "schema": "cellscript-registry-ls-idl-interface-v1", |
| 44 | + "format": "ls-idl", |
| 45 | + "format_version": "0.1", |
| 46 | + "object_role": "abi", |
| 47 | + "content_type": "application/vnd.ckb.ls-idl+json", |
| 48 | + "encoding": "linear-le-v0", |
| 49 | + "commitment": { |
| 50 | + "algorithm": "sha256", |
| 51 | + "placement": "code-cell-data-suffix-32", |
| 52 | + "digest": "<64 lowercase hexadecimal characters>" |
| 53 | + } |
| 54 | +} |
| 55 | +``` |
| 56 | + |
| 57 | +Unknown keys, alternate algorithms, alternate commitment placements, missing |
| 58 | +ABI objects, digest mismatches, and executable-suffix mismatches fail closed. |
| 59 | +The artifact bundle continues to use CKB Blake2b-256 for its executable |
| 60 | +`artifact_hash`; LS-IDL's ABI commitment remains SHA-256. These hashes have |
| 61 | +different roles and are not interchangeable. |
| 62 | + |
| 63 | +## Accepted IDL Document |
| 64 | + |
| 65 | +The document may contain only these top-level fields: |
| 66 | + |
| 67 | +- `idl_version` (optional string, matching upstream clients that default it); |
| 68 | +- `name` (optional string, matching derive output that may omit it); |
| 69 | +- `witness` (required array, at most 256 fields); |
| 70 | +- `description` (optional string); |
| 71 | +- `script_version` (optional string); and |
| 72 | +- `signing` (optional object with non-empty string fields `algorithm`, |
| 73 | + `message`, and `hasher`). |
| 74 | + |
| 75 | +Each witness field contains only `name`, `type`, `required`, and |
| 76 | +`description`. Names must be unique. The supported types are: |
| 77 | + |
| 78 | +| Type | Encoding | |
| 79 | +| --- | --- | |
| 80 | +| `uint8` | one unsigned byte | |
| 81 | +| `uint32` | four-byte little-endian unsigned integer | |
| 82 | +| `uint64` | eight-byte little-endian unsigned integer | |
| 83 | +| `secp256k1_sig` | 65 bytes | |
| 84 | +| `secp256k1_pubkey` | 33 bytes | |
| 85 | +| `schnorr_sig` | 64 bytes | |
| 86 | +| `bytes` | four-byte little-endian length followed by that many bytes | |
| 87 | + |
| 88 | +The current linear decoder treats `required` as interface metadata. It does |
| 89 | +not introduce a presence bitmap or conditional field skipping, so consumers |
| 90 | +must not interpret `required: false` as a wire-level omission rule. |
| 91 | + |
| 92 | +## Public Read API |
| 93 | + |
| 94 | +The canonical lookup is: |
| 95 | + |
| 96 | +```text |
| 97 | +GET /v1/ckb/scripts/:code_hash/interfaces/ls-idl |
| 98 | + ?network=mainnet|testnet |
| 99 | + &hash_type=data|data1|data2|type |
| 100 | + [&data_hash=0x...] |
| 101 | +``` |
| 102 | + |
| 103 | +`data_hash` is mandatory for `hash_type=type`, where a type hash alone may not |
| 104 | +uniquely identify executable data. More than one matching deployment returns |
| 105 | +`409` instead of choosing arbitrarily. |
| 106 | + |
| 107 | +The compatibility route is: |
| 108 | + |
| 109 | +```text |
| 110 | +GET /idl/:code_hash |
| 111 | +``` |
| 112 | + |
| 113 | +It is retained for existing LS-IDL clients and returns the same original |
| 114 | +bytes. New integrations should use the canonical route so network, hash type, |
| 115 | +and data-hash identity are explicit. |
| 116 | + |
| 117 | +Successful responses use |
| 118 | +`application/vnd.ckb.ls-idl+json` and expose: |
| 119 | + |
| 120 | +- `ETag`; |
| 121 | +- `x-ls-idl-format-version`; |
| 122 | +- `x-ls-idl-sha256`; |
| 123 | +- `x-ls-idl-coordinate`; |
| 124 | +- `x-ls-idl-commitment`; and |
| 125 | +- `x-ls-idl-verification`. |
| 126 | + |
| 127 | +Clients must hash the response body directly. JSON-equivalent reformatting is |
| 128 | +not byte-equivalent and therefore does not preserve the commitment. |
| 129 | + |
| 130 | +## CLI Workflow |
| 131 | + |
| 132 | +Validate a document and optionally its existing executable binding: |
| 133 | + |
| 134 | +```bash |
| 135 | +cellc artifact ls-idl validate --idl idl.json |
| 136 | +cellc artifact ls-idl validate --idl idl.json --executable lock |
| 137 | +``` |
| 138 | + |
| 139 | +Append the raw-byte digest to an executable without silently overwriting it: |
| 140 | + |
| 141 | +```bash |
| 142 | +cellc artifact ls-idl bind \ |
| 143 | + --idl idl.json \ |
| 144 | + --executable lock \ |
| 145 | + --output lock.ls-idl |
| 146 | +``` |
| 147 | + |
| 148 | +Generate a publish-ready artifact bundle and manifest: |
| 149 | + |
| 150 | +```bash |
| 151 | +cellc artifact ls-idl bundle \ |
| 152 | + --idl idl.json \ |
| 153 | + --executable lock.ls-idl \ |
| 154 | + --source lock.rs \ |
| 155 | + --namespace example \ |
| 156 | + --name example-lock \ |
| 157 | + --release 0.1.0 \ |
| 158 | + --language rust \ |
| 159 | + --hash-type data1 \ |
| 160 | + --dep-type code \ |
| 161 | + --toolchain rust-1.97.1 \ |
| 162 | + --source-revision <40-hex-git-commit> \ |
| 163 | + --output artifact.bundle.json \ |
| 164 | + --artifact-manifest-output Artifact.toml |
| 165 | +cellc publish --artifact-manifest Artifact.toml --dry-run --json |
| 166 | +``` |
| 167 | + |
| 168 | +Fetch exact bytes by deployed Script identity: |
| 169 | + |
| 170 | +```bash |
| 171 | +cellc artifact ls-idl fetch \ |
| 172 | + --code-hash 0x<64-hex> \ |
| 173 | + --hash-type data1 \ |
| 174 | + --network mainnet \ |
| 175 | + --output idl.json |
| 176 | +``` |
| 177 | + |
| 178 | +The VS Code extension exposes the validate, bind, and fetch operations through |
| 179 | +the command palette. The Registry website exposes both package-bound interface |
| 180 | +facts and a direct Script-identity lookup. |
| 181 | + |
| 182 | +## Storage And Admission |
| 183 | + |
| 184 | +Migration `0010_ls_idl_interfaces.sql` adds a partial lookup index over public, |
| 185 | +chain-verified deployed evidence. The API narrows candidates in the database, |
| 186 | +then rechecks release identity, immutable bundle identity, one-and-only-one ABI |
| 187 | +object, raw-byte digest, and profile contract before returning bytes. |
| 188 | + |
| 189 | +The normal compiler-backed Registry worker and the least-privilege |
| 190 | +artifact-only verifier both enforce the same profile. The latter has no |
| 191 | +CellScript compiler dependency. A publish that merely labels arbitrary JSON as |
| 192 | +LS-IDL, supplies a detached digest, or binds a digest to the wrong executable |
| 193 | +is rejected before it can become searchable. |
| 194 | + |
| 195 | +## Compatibility Evidence |
| 196 | + |
| 197 | +CellScript's curated vectors live in |
| 198 | +`examples/registry_ls_idl/vectors.json`. The complete upstream client vector |
| 199 | +corpus is intentionally referenced rather than copied: |
| 200 | + |
| 201 | +- `ckb-idl-derive` commit |
| 202 | + `e7ee35766b9084099e9d840ccd37d2b5d40074a1`; |
| 203 | +- `ckb-idl-client` commit |
| 204 | + `7d883e0abccba56d423449b673567ee817747936`; |
| 205 | +- upstream `test-vectors.json` SHA-256 |
| 206 | + `a9a6dca4fd0c5fcd2ca7aea6468784be7fdb29d6274049f07090cbab0ce9c1bb`. |
| 207 | + |
| 208 | +The upstream mini Registry example parses and reserialises JSON, so it is not |
| 209 | +used as the byte-preserving production storage contract. One upstream property |
| 210 | +test also constructs a Blake2b commitment while the production client verifies |
| 211 | +SHA-256. CellScript follows the production client and proposal commitment, |
| 212 | +records those upstream revisions, and tests SHA-256 end to end. |
| 213 | + |
| 214 | +## Operational Boundary |
| 215 | + |
| 216 | +Deploying the website does not deploy the Registry API. Operators must apply |
| 217 | +migration `0010_ls_idl_interfaces.sql`, roll the API and verification worker, |
| 218 | +and verify the canonical and compatibility routes before advertising live |
| 219 | +lookup availability. Existing artifact records without an interface contract |
| 220 | +remain valid and are not returned by LS-IDL lookup. |
0 commit comments