@cardananium/cquisitor-lib 0.1.0-beta.5 → 0.1.0-beta.51

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 ADDED
@@ -0,0 +1,579 @@
1
+ # Cquisitor-lib
2
+
3
+ A Cardano transaction validation and decoding library written in Rust and compiled to WebAssembly. Provides transaction validation according to ledger rules (Phase 1 and Phase 2), universal CBOR/Cardano type decoders, Plutus script decoders, and signature verification.
4
+
5
+ ## Features
6
+
7
+ ### Transaction Validation
8
+
9
+ Phase 1 validation covers balance, fees, witnesses, collateral, certificates, outputs, and transaction limits. Phase 2 executes Plutus V1/V2/V3 scripts with detailed redeemer results.
10
+
11
+ ### Universal Decoder
12
+
13
+ Decode 152+ Cardano types from hex/bech32/base58 encoding:
14
+ - Primitive types: `Address`, `PublicKey`, `PrivateKey`, `TransactionHash`, `ScriptHash`, etc.
15
+ - Complex structures: `Transaction`, `Block`, `TransactionBody`, `TransactionWitnessSet`
16
+ - Certificates: `StakeRegistration`, `PoolRegistration`, `DRepRegistration`, governance actions
17
+ - Plutus: `PlutusScript`, `PlutusData`, `Redeemer`, `ScriptRef`
18
+ - All credential types, native scripts, metadata structures
19
+
20
+ Functions:
21
+ - `get_decodable_types()` - Returns list of all supported type names
22
+ - `decode_specific_type(hex, type_name, params)` - Decode specific Cardano type
23
+ - `get_possible_types_for_input(hex)` - Suggests types that can decode given input
24
+
25
+ ### CBOR Decoder & CDDL Validation
26
+
27
+ - `cbor_to_json(cbor_hex)` - Converts raw CBOR to JSON with positional information, supporting indefinite arrays/maps and all CBOR types. Each node carries an optional `oddities` array flagging deviations from RFC 8949 deterministic encoding (overlong integers/floats, indefinite length, unsorted/duplicate map keys, non-canonical bignums). Never throws on malformed input — returns a `{ok, value}` / `{ok: false, error, partial?}` union where `error` is a structured `CborDecodeError` (kind / byte offset / byte span / semantic `path`) and `partial` is the sub-tree decoded before the failure, with every unfinished container flagged `incomplete: true`.
28
+ - `validate_cddl(cddl)` - Parses a CDDL schema; reports parse errors (with a `byte_span` for editor squiggles) and unresolved rule references (e.g. `thing = [unknown_rule, int]` → `kind: "unresolved_references"`).
29
+ - `validate_cbor_against_cddl(cbor_hex, cddl, rule_name)` - Validates a CBOR payload against a named rule. Errors carry `kind`, `expected`, semantic `path`, byte/anchor spans, a `cddl_byte_span` pointing at the failing CDDL type, and an `additional` array when multiple violations fire.
30
+ - `decode_cbor_against_cddl(cbor_hex, cddl, rule_name)` - Maps decoded CBOR onto a CDDL schema and returns labelled JSON (e.g. Cardano `[body, witness_set, bool, aux]` becomes `{transaction_body, transaction_witness_set, ...}`). Handles generics (`set<a>`), tagged sets, type rules used as field labels, and a few well-known tags (bignum → string number, datetime → ISO string). Sub-structures the schema doesn't cover surface under `@extra` / `@positional` so partial matches don't lose data.
31
+ - `cddl_outline(cddl)` - Returns one `{name, kind, span, name_span}` entry per top-level rule. Editor outline view, breadcrumbs, fuzzy "go to rule".
32
+ - `cddl_references(cddl, name)` - Returns `{definition, uses[]}` byte ranges for a rule name. Powers find-references and same-name highlighting on cursor.
33
+ - `cddl_symbol_at(cddl, offset)` - Returns the symbol under the cursor (or `null`), with `role: "definition" | "use"` and a `definition_span` pointing at its rule. Powers hover and Cmd-click go-to-definition.
34
+ - `cddl_format(cddl)` - Pretty-prints CDDL by round-tripping through the AST. Useful for format-on-save.
35
+
36
+ ### Plutus Script Decoder
37
+
38
+ - `decode_plutus_program_uplc_json(hex)` - Decodes Plutus script to UPLC AST JSON
39
+ - `decode_plutus_program_pretty_uplc(hex)` - Decodes to human-readable UPLC format
40
+
41
+ Handles double CBOR wrapping and normalization automatically.
42
+
43
+ ### Signature Verification
44
+
45
+ `check_block_or_tx_signatures(hex)` - Verifies all VKey and Catalyst witness signatures in transactions or entire blocks. Returns validation results with invalid signature details.
46
+
47
+ ### Script Execution
48
+
49
+ `execute_tx_scripts(tx_hex, utxos, cost_models)` - Executes all Plutus scripts in a transaction independently, returning execution units, logs, and success/failure for each redeemer.
50
+
51
+ ### Validation Coverage
52
+
53
+ **Phase 1 Validation:**
54
+ - Balance validation (inputs, outputs, fees, deposits, refunds)
55
+ - Fee calculation and validation (including script reference fees)
56
+ - Cryptographic witness validation (signatures, native scripts)
57
+ - Collateral validation for script transactions
58
+ - Certificate validation (stake registration, pool operations, DReps, governance)
59
+ - Output validation (minimum ADA, size limits)
60
+ - Transaction limits (size, execution units, reference scripts)
61
+ - Auxiliary data validation
62
+
63
+ **Phase 2 Validation:**
64
+ - Plutus V1, V2, and V3 script execution
65
+ - Redeemer validation with execution units
66
+ - Script context generation
67
+
68
+ See [WHAT-IS-COVERED.md](./WHAT-IS-COVERED.md) for a complete list of validation errors and warnings.
69
+
70
+ ## Installation
71
+
72
+ ### NPM/Yarn/PNPM
73
+
74
+ ```bash
75
+ npm install @cardananium/cquisitor-lib
76
+ ```
77
+
78
+ ```bash
79
+ yarn add @cardananium/cquisitor-lib
80
+ ```
81
+
82
+ ```bash
83
+ pnpm add @cardananium/cquisitor-lib
84
+ ```
85
+
86
+ ### Browser
87
+
88
+ For browser usage, import from the browser-specific build:
89
+
90
+ ```javascript
91
+ import { get_necessary_data_list_js, validate_transaction_js } from '@cardananium/cquisitor-lib/browser';
92
+ ```
93
+
94
+ ### Node.js
95
+
96
+ For Node.js usage:
97
+
98
+ ```javascript
99
+ import { get_necessary_data_list_js, validate_transaction_js } from '@cardananium/cquisitor-lib';
100
+ ```
101
+
102
+ ## Quick Start
103
+
104
+ ### Basic Usage
105
+
106
+ ```typescript
107
+ import {
108
+ get_necessary_data_list_js,
109
+ validate_transaction_js
110
+ } from '@cardananium/cquisitor-lib';
111
+
112
+ // Step 1: Parse transaction and identify required data
113
+ const txHex = "84a400..."; // Your transaction in hex format
114
+ const networkType = "mainnet"; // or "preview" | "preprod"
115
+ const necessaryDataJson = get_necessary_data_list_js(txHex, networkType);
116
+ const necessaryData = JSON.parse(necessaryDataJson);
117
+
118
+ console.log('Required UTXOs:', necessaryData.utxos);
119
+ console.log('Required accounts:', necessaryData.accounts);
120
+ console.log('Required pools:', necessaryData.pools);
121
+
122
+ // Step 2: Fetch the required data from your blockchain indexer
123
+ // (e.g., Blockfrost, Koios, or your own node)
124
+ const utxos = await fetchUtxos(necessaryData.utxos);
125
+ const accounts = await fetchAccounts(necessaryData.accounts);
126
+ const pools = await fetchPools(necessaryData.pools);
127
+ const protocolParams = await getProtocolParameters();
128
+ const currentSlot = await getCurrentSlot();
129
+
130
+ // Step 3: Build validation context
131
+ const validationContext = {
132
+ slot: currentSlot,
133
+ networkType: "mainnet", // or "preview" or "preprod"
134
+ protocolParameters: protocolParams,
135
+ utxoSet: utxos,
136
+ accountContexts: accounts,
137
+ poolContexts: pools,
138
+ drepContexts: [],
139
+ govActionContexts: [],
140
+ lastEnactedGovAction: [],
141
+ currentCommitteeMembers: [],
142
+ potentialCommitteeMembers: [],
143
+ treasuryValue: 0n
144
+ };
145
+
146
+ // Step 4: Validate the transaction
147
+ const resultJson = validate_transaction_js(
148
+ txHex,
149
+ JSON.stringify(validationContext)
150
+ );
151
+ const result = JSON.parse(resultJson);
152
+
153
+ // Step 5: Check validation results
154
+ if (result.errors.length > 0) {
155
+ console.error('❌ Transaction validation failed:');
156
+ result.errors.forEach(err => {
157
+ console.error(`- ${err.error_message}`);
158
+ if (err.hint) {
159
+ console.error(` Hint: ${err.hint}`);
160
+ }
161
+ });
162
+ } else if (result.phase2_errors.length > 0) {
163
+ console.error('❌ Script execution failed:');
164
+ result.phase2_errors.forEach(err => {
165
+ console.error(`- ${err.error_message}`);
166
+ });
167
+ } else {
168
+ console.log('✅ Transaction is valid!');
169
+ }
170
+
171
+ // Check for warnings
172
+ if (result.warnings.length > 0) {
173
+ console.warn('⚠️ Warnings:', result.warnings);
174
+ }
175
+ ```
176
+
177
+ ### Complete Example with Error Handling
178
+
179
+ ```typescript
180
+ import {
181
+ get_necessary_data_list_js,
182
+ validate_transaction_js
183
+ } from '@cardananium/cquisitor-lib';
184
+
185
+ async function validateTransaction(txHex: string): Promise<boolean> {
186
+ try {
187
+ // Parse transaction
188
+ const necessaryDataJson = get_necessary_data_list_js(txHex, "mainnet");
189
+ const necessaryData = JSON.parse(necessaryDataJson);
190
+
191
+ // Fetch required blockchain data
192
+ // (Implementation depends on your data source)
193
+ const context = await buildValidationContext(necessaryData);
194
+
195
+ // Validate
196
+ const resultJson = validate_transaction_js(
197
+ txHex,
198
+ JSON.stringify(context)
199
+ );
200
+ const result = JSON.parse(resultJson);
201
+
202
+ // Log detailed results
203
+ const hasErrors = result.errors.length > 0 || result.phase2_errors.length > 0;
204
+
205
+ if (!hasErrors) {
206
+ console.log('✅ Transaction is valid!');
207
+
208
+ // Log redeemer execution details
209
+ result.eval_redeemer_results.forEach(redeemer => {
210
+ console.log(`Redeemer ${redeemer.tag}[${redeemer.index}]:`);
211
+ console.log(` Success: ${redeemer.success}`);
212
+ console.log(` Ex units: ${JSON.stringify(redeemer.calculated_ex_units)}`);
213
+ if (redeemer.logs.length > 0) {
214
+ console.log(` Logs: ${redeemer.logs.join(', ')}`);
215
+ }
216
+ });
217
+ } else {
218
+ console.error('❌ Validation failed');
219
+ [...result.errors, ...result.phase2_errors].forEach(err => {
220
+ console.error(`- ${err.error_message}`);
221
+ });
222
+ }
223
+
224
+ return !hasErrors;
225
+
226
+ } catch (error) {
227
+ console.error('Validation error:', error);
228
+ return false;
229
+ }
230
+ }
231
+ ```
232
+
233
+ ## API Reference
234
+
235
+ ### Transaction Validation
236
+
237
+ #### `get_necessary_data_list_js(tx_hex: string, network_type: "mainnet" | "preview" | "preprod"): string`
238
+
239
+ Extracts required blockchain data for validation. `network_type` determines the bech32 prefix used when deriving stake/reward addresses for `accounts`, `pools`, and `dReps`.
240
+
241
+ ```typescript
242
+ const necessaryData = JSON.parse(get_necessary_data_list_js(txHex, "mainnet"));
243
+ // Returns: { utxos, accounts, pools, dReps, govActions, ... }
244
+ ```
245
+
246
+ #### `validate_transaction_js(tx_hex: string, validation_context: string): string`
247
+
248
+ Validates transaction with full ledger rules.
249
+
250
+ ```typescript
251
+ const result = JSON.parse(validate_transaction_js(txHex, JSON.stringify(context)));
252
+ // Returns: { errors, warnings, phase2_errors, phase2_warnings, eval_redeemer_results }
253
+ ```
254
+
255
+ #### `get_utxo_list_from_tx(tx_hex: string): string[]`
256
+
257
+ Extracts all UTxO references (inputs + collateral + reference inputs) from transaction.
258
+
259
+ #### `get_ref_script_bytes(tx_hex: string, output_index: number): string`
260
+
261
+ Returns the hex-encoded CBOR bytes of the reference script embedded in `outputs[output_index]`. Returns an empty string if the output has no reference script or the index is out of range.
262
+
263
+ ```typescript
264
+ const scriptHex = get_ref_script_bytes(txHex, 0);
265
+ ```
266
+
267
+ #### `extract_hashes_from_transaction_js(tx_hex: string): string`
268
+
269
+ Returns a JSON-serialized `ExtractedHashes` with every script / datum / redeemer / metadata / auxiliary-data hash referenced by the transaction (witness set, outputs with inline scripts/datums, auxiliary data). Useful for building indexers or caches.
270
+
271
+ ```typescript
272
+ const hashes = JSON.parse(extract_hashes_from_transaction_js(txHex));
273
+ // { witness_native_script_hashes, witness_plutus_scripts, witness_datum_hashes, ... }
274
+ ```
275
+
276
+ ### Universal Decoder
277
+
278
+ #### `get_decodable_types(): string[]`
279
+
280
+ Returns array of all 152+ decodable type names.
281
+
282
+ ```typescript
283
+ const types = get_decodable_types();
284
+ // ['Address', 'Transaction', 'PlutusScript', 'PublicKey', ...]
285
+ ```
286
+
287
+ #### `decode_specific_type(input: string, type_name: string, params: DecodingParams): any`
288
+
289
+ Decodes specific Cardano type from hex/bech32/base58.
290
+
291
+ ```typescript
292
+ const address = decode_specific_type(
293
+ "addr1...",
294
+ "Address",
295
+ { plutusDataSchema: "DetailedSchema" }
296
+ );
297
+
298
+ const tx = decode_specific_type(
299
+ "84a400...",
300
+ "Transaction",
301
+ { plutusDataSchema: "DetailedSchema" }
302
+ );
303
+ ```
304
+
305
+ #### `get_possible_types_for_input(input: string): string[]`
306
+
307
+ Suggests which types can decode the given input.
308
+
309
+ ```typescript
310
+ const possibleTypes = get_possible_types_for_input("e1a...");
311
+ // ['Address', 'BaseAddress', 'EnterpriseAddress', ...]
312
+ ```
313
+
314
+ ### CBOR Decoder
315
+
316
+ #### `cbor_to_json(cbor_hex: string): CborDecodeResult`
317
+
318
+ Converts CBOR to JSON with positional metadata. Each node has `position_info` (byte span of its header) and, for containers/tags, `struct_position_info` (span of the whole subtree). Non-canonical encoding deviations (per RFC 8949 §4.1/§4.2) are flagged locally on the offending node via an optional `oddities: CborOddity[]` field — canonical inputs omit the field entirely.
319
+
320
+ The function **never throws** on malformed input. On success it returns `{ ok: true, value }`; on failure `{ ok: false, error, partial? }` where `error` is a structured `CborDecodeError` and `partial` is the sub-tree decoded up to the failure point:
321
+
322
+ ```typescript
323
+ const r = cbor_to_json("a26461646472...");
324
+ if (r.ok) {
325
+ // r.value — the full positional tree; each node may carry oddities like:
326
+ // { kind: "IntNotShortest", detail: "value 15 uses 2-byte header, shortest is 1" }
327
+ // { kind: "IndefiniteLength", detail: "indefinite-length map" }
328
+ // { kind: "MapKeysNotSorted", detail: "key at offset 3 sorts after key at offset 5" }
329
+ // { kind: "DuplicateMapKeys", detail: "duplicate key at offsets 3 and 6" }
330
+ // { kind: "BignumForSmallInt", detail: "unsigned bignum fits in a native CBOR integer" }
331
+ } else {
332
+ // r.error: { kind, offset?, byte_span?, path, message }
333
+ // kind — machine-readable tag ("invalid_syntax", "unexpected_eof", ...).
334
+ // offset — byte where decoding stopped.
335
+ // byte_span — { offset, length } when the failure pins a range.
336
+ // path — structural location, e.g. "$.entries[1].value[0]".
337
+ // r.partial (optional) — same shape as a CborValue, but every unfinished
338
+ // container carries `incomplete: true`, and partial map entries carry
339
+ // `incomplete_at: "key" | "value"` on the half that didn't parse.
340
+ }
341
+ ```
342
+
343
+ See `CborOddityKind` and `CborDecodeErrorKind` in the type definitions for the full lists.
344
+
345
+ #### `validate_cddl(cddl: string): { valid: boolean, error?: object }`
346
+
347
+ Parses a CDDL schema and reports whether it is well-formed. Beyond surface parse errors this also catches **dangling rule references** at parse time, surfaced as `kind: "unresolved_references"`.
348
+
349
+ ```typescript
350
+ validate_cddl("thing = {n: uint}");
351
+ // { valid: true }
352
+
353
+ validate_cddl("thing = [unknown_rule, int]");
354
+ // { valid: false, error: { kind: "unresolved_references",
355
+ // message: "missing definition for rule unknown_rule" } }
356
+ ```
357
+
358
+ `error.kind` values: `"parse_error"`, `"unresolved_references"`.
359
+
360
+ #### `validate_cbor_against_cddl(cbor_hex: string, cddl: string, rule_name: string): { valid: boolean, error?: object }`
361
+
362
+ Validates a CBOR payload against a specific rule in a CDDL schema. The rule does not have to be the first rule in the document — when it isn't, the validator wraps it in a synthetic root internally.
363
+
364
+ ```typescript
365
+ validate_cbor_against_cddl("01", "thing = tstr", "thing");
366
+ // {
367
+ // valid: false,
368
+ // error: {
369
+ // kind: "mismatch",
370
+ // expected: "tstr",
371
+ // path: "$",
372
+ // byte_spans: [{ offset: 0, length: 1 }],
373
+ // cddl_byte_span: { offset: 8, length: 4, line: 1 }, // points at `tstr`
374
+ // message: "expected type tstr, got Integer(Integer(1))"
375
+ // }
376
+ // }
377
+ ```
378
+
379
+ `error.cddl_byte_span` carries the byte range in the **CDDL source** pointing at the type the validator tried (and failed) to apply — useful for highlighting the offending rule in an editor. It's synthesised by walking the AST in parallel with `path`, so it's available for any error that has a meaningful `path`. When the `rule_name` you passed isn't the first rule of the document, the offsets are still expressed in *your* CDDL coordinates (the wrapper we use internally is invisible to callers).
380
+
381
+ `error.kind` values: `"parse_error"`, `"unresolved_references"`, `"missing_rule"`, `"input_parse"`, `"mismatch"`, `"map_cut"`, `"generic"`. When multiple violations fire, the headline goes in the top-level fields and the rest land in `error.additional`.
382
+
383
+ #### `decode_cbor_against_cddl(cbor_hex: string, cddl: string, rule_name: string): unknown`
384
+
385
+ Walks the CDDL alongside the decoded CBOR and produces a JSON tree where positional/numeric-keyed structures are replaced with the names the schema declares. Useful for turning a Cardano transaction CBOR into something inspectable without hand-mapping every field.
386
+
387
+ ```typescript
388
+ decode_cbor_against_cddl(txHex, conwayCddl, "transaction");
389
+ // {
390
+ // transaction_body: {
391
+ // 0: { "@tag": 258, "@value": [{ transaction_id: "16b6...", index: 0 }] },
392
+ // 1: [{ address: "00ae...", amount: 1_000_000 }, ...],
393
+ // 2: 200000,
394
+ // 7: "bdaa..."
395
+ // },
396
+ // transaction_witness_set: {
397
+ // 0: { "@tag": 258, "@value": [{ vkey: "f8f5...", signature: "1e14..." }] }
398
+ // },
399
+ // "@positional": [true, { "@tag": 259, "@value": {} }]
400
+ // }
401
+ ```
402
+
403
+ Recognised features: type choices (first match wins), generics (`set<a>`), tagged data (well-known tags 0/2/3 specialised to ISO date / bignum string), rule references, optionals/repetitions, prelude scalars. Sub-structures the schema doesn't cover or that don't match any choice fall back to a raw form under `@extra` (maps) or `@positional` (arrays) so data is never silently dropped.
404
+
405
+ #### CDDL editor primitives
406
+
407
+ For embedding a CDDL editor / inspector. All four functions parse the document with the same checked parser as `validate_cddl` and throw on parse errors.
408
+
409
+ ```typescript
410
+ // Document outline — list every rule with its byte range.
411
+ cddl_outline("alpha = uint\nbeta = (a: int)");
412
+ // [
413
+ // {name: "alpha", kind: "type", span: {offset: 0, length: 12, line: 1},
414
+ // name_span: {offset: 0, length: 5, line: 1}},
415
+ // {name: "beta", kind: "group", span: {offset: 13, length: 14, line: 2},
416
+ // name_span: {offset: 13, length: 4, line: 2}}
417
+ // ]
418
+
419
+ // Find every use of a rule — the IDE "Find references" affordance.
420
+ cddl_references("coin = uint\noutput = [bstr, coin]\nfee = coin", "coin");
421
+ // {definition: {offset: 0, length: 4, line: 1},
422
+ // uses: [
423
+ // {offset: 26, length: 4, line: 2},
424
+ // {offset: 38, length: 4, line: 3}
425
+ // ]}
426
+
427
+ // Symbol at cursor — hover info and Cmd-click target.
428
+ cddl_symbol_at("coin = uint\nfee = coin", /* offset = */ 18);
429
+ // {name: "coin", kind: "rule_reference", role: "use",
430
+ // span: {offset: 18, length: 4, line: 2},
431
+ // definition_span: {offset: 0, length: 4, line: 1},
432
+ // rule_span: {offset: 0, length: 11, line: 1}}
433
+
434
+ // Re-format — round-trip via Display.
435
+ cddl_format("alpha = uint");
436
+ // "alpha = uint"
437
+ ```
438
+
439
+ `validate_cddl` itself returns a `byte_span` on parser errors so editor-side squiggles can underline the offending position directly:
440
+
441
+ ```typescript
442
+ validate_cddl("alpha = ");
443
+ // {valid: false,
444
+ // error: {kind: "parse_error", message: "...", byte_span: {offset: 8, length: 0, line: 1}}}
445
+ ```
446
+
447
+ ### Plutus Script Decoder
448
+
449
+ #### `decode_plutus_program_uplc_json(hex: string): ProgramJson`
450
+
451
+ Decodes Plutus script to UPLC AST in JSON format.
452
+
453
+ ```typescript
454
+ const program = decode_plutus_program_uplc_json("59012a01000...");
455
+ // Returns: { version: [1,0,0], program: { ... } }
456
+ ```
457
+
458
+ #### `decode_plutus_program_pretty_uplc(hex: string): string`
459
+
460
+ Decodes Plutus script to human-readable UPLC.
461
+
462
+ ```typescript
463
+ const code = decode_plutus_program_pretty_uplc("59012a01000...");
464
+ // Returns: "(program 1.0.0 (lam x_0 ...))"
465
+ ```
466
+
467
+ ### Signature Verification
468
+
469
+ #### `check_block_or_tx_signatures(hex: string): CheckSignaturesResult`
470
+
471
+ Verifies all signatures in transaction or block.
472
+
473
+ ```typescript
474
+ const result = check_block_or_tx_signatures(txHex);
475
+ // Returns: { valid, results: [{ valid, tx_hash, invalidVkeyWitnesses, invalidCatalystWitnesses }] }
476
+ ```
477
+
478
+ ### Script Execution
479
+
480
+ #### `execute_tx_scripts(tx_hex: string, utxos: UTxO[], cost_models: CostModels): ExecuteTxScriptsResult`
481
+
482
+ Executes all Plutus scripts in transaction.
483
+
484
+ ```typescript
485
+ const result = execute_tx_scripts(txHex, utxos, costModels);
486
+ // Returns execution units, logs, and status for each redeemer
487
+ ```
488
+
489
+ ## Data Sources
490
+
491
+ To populate the validation context, you'll need to fetch blockchain data from a Cardano indexer or node. Recommended sources:
492
+
493
+ - **[Blockfrost](https://blockfrost.io/)** - Reliable API with generous free tier
494
+ - **[Koios](https://koios.rest/)** - Community-driven API with rich queries
495
+ - **Cardano Node** - Direct access via `cardano-cli` or `cardano-db-sync`
496
+ - **Custom Indexer** - Roll your own using Pallas or similar libraries
497
+
498
+ ## Building from Source
499
+
500
+ ### Prerequisites
501
+
502
+ - Rust 1.83 or newer
503
+ - `wasm-pack`
504
+ - Node.js and npm
505
+
506
+ ### Build Steps
507
+
508
+ ```bash
509
+ # Clone the repository
510
+ git clone https://github.com/your-org/cquisitor-lib.git
511
+ cd cquisitor-lib
512
+
513
+ # Build for Node.js
514
+ npm run rust:build-wasm:node
515
+
516
+ # Build for browser
517
+ npm run rust:build-wasm:browser
518
+
519
+ # Build both targets
520
+ npm run build-all
521
+
522
+ # Generate TypeScript definitions
523
+ npm run generate-dts
524
+ ```
525
+
526
+ ## Type Definitions
527
+
528
+ Full TypeScript type definitions are available in the package and cover all input and output types. The main types include:
529
+
530
+ - `NecessaryInputData` - Required blockchain data for validation
531
+ - `ValidationInputContext` - Complete validation context structure
532
+ - `ValidationResult` - Validation results with errors and warnings
533
+ - `ProtocolParameters` - Cardano protocol parameters
534
+ - And many more detailed types for UTXOs, certificates, governance, etc.
535
+
536
+ See [types/cquisitor_lib.d.ts](./types/cquisitor_lib.d.ts) for the complete type definitions.
537
+
538
+ ## Performance
539
+
540
+ Written in Rust and compiled to WebAssembly for near-native performance in browsers and Node.js.
541
+
542
+ ## Contributing
543
+
544
+ Contributions are welcome! Please feel free to submit pull requests or open issues for bugs and feature requests.
545
+
546
+ ### Development Workflow
547
+
548
+ 1. Fork the repository
549
+ 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
550
+ 3. Make your changes
551
+ 4. Run tests (`cargo test`)
552
+ 5. Commit your changes (`git commit -m 'Add amazing feature'`)
553
+ 6. Push to the branch (`git push origin feature/amazing-feature`)
554
+ 7. Open a Pull Request
555
+
556
+ ## License
557
+
558
+ This project is licensed under the Apache License 2.0 - see the [LICENSE](./LICENSE) file for details.
559
+
560
+ ## Acknowledgments
561
+
562
+ This library builds upon the excellent work of the Cardano community, particularly:
563
+
564
+ - [cardano-serialization-lib](https://github.com/Emurgo/cardano-serialization-lib) - For cardano structures deserialization
565
+ - [Pallas](https://github.com/txpipe/pallas) - Cardano primitives
566
+ - [UPLC](https://github.com/aiken-lang/aiken/tree/main/crates/uplc) - Plutus script execution
567
+ - The Cardano Ledger specification team
568
+
569
+ ## Support
570
+
571
+ For questions and support:
572
+
573
+ - 📖 Check the [API Documentation](./API_DOCUMENTATION.md)
574
+ - 🐛 Report bugs via [GitHub Issues](https://github.com/cardananium/cquisitor-lib/issues)
575
+
576
+ ---
577
+
578
+ Made with ❤️ for the Cardano ecosystem
579
+