@cardananium/cquisitor-lib 0.1.0-beta.5 → 0.1.0-beta.50
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 +530 -0
- package/browser/cquisitor_lib.d.ts +1346 -36
- package/browser/cquisitor_lib.js +9 -39367
- package/browser/cquisitor_lib_bg.js +30435 -0
- package/browser/cquisitor_lib_bg.wasm +0 -0
- package/browser/cquisitor_lib_bg.wasm.d.ts +2449 -2434
- package/node/cquisitor_lib.d.ts +1346 -36
- package/node/cquisitor_lib.js +23223 -32075
- package/node/cquisitor_lib_bg.wasm +0 -0
- package/node/cquisitor_lib_bg.wasm.d.ts +2449 -2434
- package/package.json +5 -2
package/README.md
ADDED
|
@@ -0,0 +1,530 @@
|
|
|
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 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, 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
|
+
|
|
32
|
+
### Plutus Script Decoder
|
|
33
|
+
|
|
34
|
+
- `decode_plutus_program_uplc_json(hex)` - Decodes Plutus script to UPLC AST JSON
|
|
35
|
+
- `decode_plutus_program_pretty_uplc(hex)` - Decodes to human-readable UPLC format
|
|
36
|
+
|
|
37
|
+
Handles double CBOR wrapping and normalization automatically.
|
|
38
|
+
|
|
39
|
+
### Signature Verification
|
|
40
|
+
|
|
41
|
+
`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.
|
|
42
|
+
|
|
43
|
+
### Script Execution
|
|
44
|
+
|
|
45
|
+
`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.
|
|
46
|
+
|
|
47
|
+
### Validation Coverage
|
|
48
|
+
|
|
49
|
+
**Phase 1 Validation:**
|
|
50
|
+
- Balance validation (inputs, outputs, fees, deposits, refunds)
|
|
51
|
+
- Fee calculation and validation (including script reference fees)
|
|
52
|
+
- Cryptographic witness validation (signatures, native scripts)
|
|
53
|
+
- Collateral validation for script transactions
|
|
54
|
+
- Certificate validation (stake registration, pool operations, DReps, governance)
|
|
55
|
+
- Output validation (minimum ADA, size limits)
|
|
56
|
+
- Transaction limits (size, execution units, reference scripts)
|
|
57
|
+
- Auxiliary data validation
|
|
58
|
+
|
|
59
|
+
**Phase 2 Validation:**
|
|
60
|
+
- Plutus V1, V2, and V3 script execution
|
|
61
|
+
- Redeemer validation with execution units
|
|
62
|
+
- Script context generation
|
|
63
|
+
|
|
64
|
+
See [WHAT-IS-COVERED.md](./WHAT-IS-COVERED.md) for a complete list of validation errors and warnings.
|
|
65
|
+
|
|
66
|
+
## Installation
|
|
67
|
+
|
|
68
|
+
### NPM/Yarn/PNPM
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
npm install @cardananium/cquisitor-lib
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
yarn add @cardananium/cquisitor-lib
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
pnpm add @cardananium/cquisitor-lib
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Browser
|
|
83
|
+
|
|
84
|
+
For browser usage, import from the browser-specific build:
|
|
85
|
+
|
|
86
|
+
```javascript
|
|
87
|
+
import { get_necessary_data_list_js, validate_transaction_js } from '@cardananium/cquisitor-lib/browser';
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Node.js
|
|
91
|
+
|
|
92
|
+
For Node.js usage:
|
|
93
|
+
|
|
94
|
+
```javascript
|
|
95
|
+
import { get_necessary_data_list_js, validate_transaction_js } from '@cardananium/cquisitor-lib';
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Quick Start
|
|
99
|
+
|
|
100
|
+
### Basic Usage
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
import {
|
|
104
|
+
get_necessary_data_list_js,
|
|
105
|
+
validate_transaction_js
|
|
106
|
+
} from '@cardananium/cquisitor-lib';
|
|
107
|
+
|
|
108
|
+
// Step 1: Parse transaction and identify required data
|
|
109
|
+
const txHex = "84a400..."; // Your transaction in hex format
|
|
110
|
+
const networkType = "mainnet"; // or "preview" | "preprod"
|
|
111
|
+
const necessaryDataJson = get_necessary_data_list_js(txHex, networkType);
|
|
112
|
+
const necessaryData = JSON.parse(necessaryDataJson);
|
|
113
|
+
|
|
114
|
+
console.log('Required UTXOs:', necessaryData.utxos);
|
|
115
|
+
console.log('Required accounts:', necessaryData.accounts);
|
|
116
|
+
console.log('Required pools:', necessaryData.pools);
|
|
117
|
+
|
|
118
|
+
// Step 2: Fetch the required data from your blockchain indexer
|
|
119
|
+
// (e.g., Blockfrost, Koios, or your own node)
|
|
120
|
+
const utxos = await fetchUtxos(necessaryData.utxos);
|
|
121
|
+
const accounts = await fetchAccounts(necessaryData.accounts);
|
|
122
|
+
const pools = await fetchPools(necessaryData.pools);
|
|
123
|
+
const protocolParams = await getProtocolParameters();
|
|
124
|
+
const currentSlot = await getCurrentSlot();
|
|
125
|
+
|
|
126
|
+
// Step 3: Build validation context
|
|
127
|
+
const validationContext = {
|
|
128
|
+
slot: currentSlot,
|
|
129
|
+
networkType: "mainnet", // or "preview" or "preprod"
|
|
130
|
+
protocolParameters: protocolParams,
|
|
131
|
+
utxoSet: utxos,
|
|
132
|
+
accountContexts: accounts,
|
|
133
|
+
poolContexts: pools,
|
|
134
|
+
drepContexts: [],
|
|
135
|
+
govActionContexts: [],
|
|
136
|
+
lastEnactedGovAction: [],
|
|
137
|
+
currentCommitteeMembers: [],
|
|
138
|
+
potentialCommitteeMembers: [],
|
|
139
|
+
treasuryValue: 0n
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
// Step 4: Validate the transaction
|
|
143
|
+
const resultJson = validate_transaction_js(
|
|
144
|
+
txHex,
|
|
145
|
+
JSON.stringify(validationContext)
|
|
146
|
+
);
|
|
147
|
+
const result = JSON.parse(resultJson);
|
|
148
|
+
|
|
149
|
+
// Step 5: Check validation results
|
|
150
|
+
if (result.errors.length > 0) {
|
|
151
|
+
console.error('❌ Transaction validation failed:');
|
|
152
|
+
result.errors.forEach(err => {
|
|
153
|
+
console.error(`- ${err.error_message}`);
|
|
154
|
+
if (err.hint) {
|
|
155
|
+
console.error(` Hint: ${err.hint}`);
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
} else if (result.phase2_errors.length > 0) {
|
|
159
|
+
console.error('❌ Script execution failed:');
|
|
160
|
+
result.phase2_errors.forEach(err => {
|
|
161
|
+
console.error(`- ${err.error_message}`);
|
|
162
|
+
});
|
|
163
|
+
} else {
|
|
164
|
+
console.log('✅ Transaction is valid!');
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Check for warnings
|
|
168
|
+
if (result.warnings.length > 0) {
|
|
169
|
+
console.warn('⚠️ Warnings:', result.warnings);
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Complete Example with Error Handling
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
import {
|
|
177
|
+
get_necessary_data_list_js,
|
|
178
|
+
validate_transaction_js
|
|
179
|
+
} from '@cardananium/cquisitor-lib';
|
|
180
|
+
|
|
181
|
+
async function validateTransaction(txHex: string): Promise<boolean> {
|
|
182
|
+
try {
|
|
183
|
+
// Parse transaction
|
|
184
|
+
const necessaryDataJson = get_necessary_data_list_js(txHex, "mainnet");
|
|
185
|
+
const necessaryData = JSON.parse(necessaryDataJson);
|
|
186
|
+
|
|
187
|
+
// Fetch required blockchain data
|
|
188
|
+
// (Implementation depends on your data source)
|
|
189
|
+
const context = await buildValidationContext(necessaryData);
|
|
190
|
+
|
|
191
|
+
// Validate
|
|
192
|
+
const resultJson = validate_transaction_js(
|
|
193
|
+
txHex,
|
|
194
|
+
JSON.stringify(context)
|
|
195
|
+
);
|
|
196
|
+
const result = JSON.parse(resultJson);
|
|
197
|
+
|
|
198
|
+
// Log detailed results
|
|
199
|
+
const hasErrors = result.errors.length > 0 || result.phase2_errors.length > 0;
|
|
200
|
+
|
|
201
|
+
if (!hasErrors) {
|
|
202
|
+
console.log('✅ Transaction is valid!');
|
|
203
|
+
|
|
204
|
+
// Log redeemer execution details
|
|
205
|
+
result.eval_redeemer_results.forEach(redeemer => {
|
|
206
|
+
console.log(`Redeemer ${redeemer.tag}[${redeemer.index}]:`);
|
|
207
|
+
console.log(` Success: ${redeemer.success}`);
|
|
208
|
+
console.log(` Ex units: ${JSON.stringify(redeemer.calculated_ex_units)}`);
|
|
209
|
+
if (redeemer.logs.length > 0) {
|
|
210
|
+
console.log(` Logs: ${redeemer.logs.join(', ')}`);
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
} else {
|
|
214
|
+
console.error('❌ Validation failed');
|
|
215
|
+
[...result.errors, ...result.phase2_errors].forEach(err => {
|
|
216
|
+
console.error(`- ${err.error_message}`);
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return !hasErrors;
|
|
221
|
+
|
|
222
|
+
} catch (error) {
|
|
223
|
+
console.error('Validation error:', error);
|
|
224
|
+
return false;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## API Reference
|
|
230
|
+
|
|
231
|
+
### Transaction Validation
|
|
232
|
+
|
|
233
|
+
#### `get_necessary_data_list_js(tx_hex: string, network_type: "mainnet" | "preview" | "preprod"): string`
|
|
234
|
+
|
|
235
|
+
Extracts required blockchain data for validation. `network_type` determines the bech32 prefix used when deriving stake/reward addresses for `accounts`, `pools`, and `dReps`.
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
const necessaryData = JSON.parse(get_necessary_data_list_js(txHex, "mainnet"));
|
|
239
|
+
// Returns: { utxos, accounts, pools, dReps, govActions, ... }
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
#### `validate_transaction_js(tx_hex: string, validation_context: string): string`
|
|
243
|
+
|
|
244
|
+
Validates transaction with full ledger rules.
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
const result = JSON.parse(validate_transaction_js(txHex, JSON.stringify(context)));
|
|
248
|
+
// Returns: { errors, warnings, phase2_errors, phase2_warnings, eval_redeemer_results }
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
#### `get_utxo_list_from_tx(tx_hex: string): string[]`
|
|
252
|
+
|
|
253
|
+
Extracts all UTxO references (inputs + collateral + reference inputs) from transaction.
|
|
254
|
+
|
|
255
|
+
#### `get_ref_script_bytes(tx_hex: string, output_index: number): string`
|
|
256
|
+
|
|
257
|
+
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.
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
const scriptHex = get_ref_script_bytes(txHex, 0);
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
#### `extract_hashes_from_transaction_js(tx_hex: string): string`
|
|
264
|
+
|
|
265
|
+
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.
|
|
266
|
+
|
|
267
|
+
```typescript
|
|
268
|
+
const hashes = JSON.parse(extract_hashes_from_transaction_js(txHex));
|
|
269
|
+
// { witness_native_script_hashes, witness_plutus_scripts, witness_datum_hashes, ... }
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Universal Decoder
|
|
273
|
+
|
|
274
|
+
#### `get_decodable_types(): string[]`
|
|
275
|
+
|
|
276
|
+
Returns array of all 152+ decodable type names.
|
|
277
|
+
|
|
278
|
+
```typescript
|
|
279
|
+
const types = get_decodable_types();
|
|
280
|
+
// ['Address', 'Transaction', 'PlutusScript', 'PublicKey', ...]
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
#### `decode_specific_type(input: string, type_name: string, params: DecodingParams): any`
|
|
284
|
+
|
|
285
|
+
Decodes specific Cardano type from hex/bech32/base58.
|
|
286
|
+
|
|
287
|
+
```typescript
|
|
288
|
+
const address = decode_specific_type(
|
|
289
|
+
"addr1...",
|
|
290
|
+
"Address",
|
|
291
|
+
{ plutusDataSchema: "DetailedSchema" }
|
|
292
|
+
);
|
|
293
|
+
|
|
294
|
+
const tx = decode_specific_type(
|
|
295
|
+
"84a400...",
|
|
296
|
+
"Transaction",
|
|
297
|
+
{ plutusDataSchema: "DetailedSchema" }
|
|
298
|
+
);
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
#### `get_possible_types_for_input(input: string): string[]`
|
|
302
|
+
|
|
303
|
+
Suggests which types can decode the given input.
|
|
304
|
+
|
|
305
|
+
```typescript
|
|
306
|
+
const possibleTypes = get_possible_types_for_input("e1a...");
|
|
307
|
+
// ['Address', 'BaseAddress', 'EnterpriseAddress', ...]
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### CBOR Decoder
|
|
311
|
+
|
|
312
|
+
#### `cbor_to_json(cbor_hex: string): CborDecodeResult`
|
|
313
|
+
|
|
314
|
+
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.
|
|
315
|
+
|
|
316
|
+
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:
|
|
317
|
+
|
|
318
|
+
```typescript
|
|
319
|
+
const r = cbor_to_json("a26461646472...");
|
|
320
|
+
if (r.ok) {
|
|
321
|
+
// r.value — the full positional tree; each node may carry oddities like:
|
|
322
|
+
// { kind: "IntNotShortest", detail: "value 15 uses 2-byte header, shortest is 1" }
|
|
323
|
+
// { kind: "IndefiniteLength", detail: "indefinite-length map" }
|
|
324
|
+
// { kind: "MapKeysNotSorted", detail: "key at offset 3 sorts after key at offset 5" }
|
|
325
|
+
// { kind: "DuplicateMapKeys", detail: "duplicate key at offsets 3 and 6" }
|
|
326
|
+
// { kind: "BignumForSmallInt", detail: "unsigned bignum fits in a native CBOR integer" }
|
|
327
|
+
} else {
|
|
328
|
+
// r.error: { kind, offset?, byte_span?, path, message }
|
|
329
|
+
// kind — machine-readable tag ("invalid_syntax", "unexpected_eof", ...).
|
|
330
|
+
// offset — byte where decoding stopped.
|
|
331
|
+
// byte_span — { offset, length } when the failure pins a range.
|
|
332
|
+
// path — structural location, e.g. "$.entries[1].value[0]".
|
|
333
|
+
// r.partial (optional) — same shape as a CborValue, but every unfinished
|
|
334
|
+
// container carries `incomplete: true`, and partial map entries carry
|
|
335
|
+
// `incomplete_at: "key" | "value"` on the half that didn't parse.
|
|
336
|
+
}
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
See `CborOddityKind` and `CborDecodeErrorKind` in the type definitions for the full lists.
|
|
340
|
+
|
|
341
|
+
#### `validate_cddl(cddl: string): { valid: boolean, error?: object }`
|
|
342
|
+
|
|
343
|
+
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"`.
|
|
344
|
+
|
|
345
|
+
```typescript
|
|
346
|
+
validate_cddl("thing = {n: uint}");
|
|
347
|
+
// { valid: true }
|
|
348
|
+
|
|
349
|
+
validate_cddl("thing = [unknown_rule, int]");
|
|
350
|
+
// { valid: false, error: { kind: "unresolved_references",
|
|
351
|
+
// message: "missing definition for rule unknown_rule" } }
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
`error.kind` values: `"parse_error"`, `"unresolved_references"`.
|
|
355
|
+
|
|
356
|
+
#### `validate_cbor_against_cddl(cbor_hex: string, cddl: string, rule_name: string): { valid: boolean, error?: object }`
|
|
357
|
+
|
|
358
|
+
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.
|
|
359
|
+
|
|
360
|
+
```typescript
|
|
361
|
+
validate_cbor_against_cddl("01", "thing = tstr", "thing");
|
|
362
|
+
// {
|
|
363
|
+
// valid: false,
|
|
364
|
+
// error: {
|
|
365
|
+
// kind: "mismatch",
|
|
366
|
+
// expected: "tstr",
|
|
367
|
+
// path: "$",
|
|
368
|
+
// byte_spans: [{ offset: 0, length: 1 }],
|
|
369
|
+
// message: "expected type tstr, got Integer(Integer(1))"
|
|
370
|
+
// }
|
|
371
|
+
// }
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
`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`.
|
|
375
|
+
|
|
376
|
+
#### `decode_cbor_against_cddl(cbor_hex: string, cddl: string, rule_name: string): unknown`
|
|
377
|
+
|
|
378
|
+
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.
|
|
379
|
+
|
|
380
|
+
```typescript
|
|
381
|
+
decode_cbor_against_cddl(txHex, conwayCddl, "transaction");
|
|
382
|
+
// {
|
|
383
|
+
// transaction_body: {
|
|
384
|
+
// 0: { "@tag": 258, "@value": [{ transaction_id: "16b6...", index: 0 }] },
|
|
385
|
+
// 1: [{ address: "00ae...", amount: 1_000_000 }, ...],
|
|
386
|
+
// 2: 200000,
|
|
387
|
+
// 7: "bdaa..."
|
|
388
|
+
// },
|
|
389
|
+
// transaction_witness_set: {
|
|
390
|
+
// 0: { "@tag": 258, "@value": [{ vkey: "f8f5...", signature: "1e14..." }] }
|
|
391
|
+
// },
|
|
392
|
+
// "@positional": [true, { "@tag": 259, "@value": {} }]
|
|
393
|
+
// }
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
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.
|
|
397
|
+
|
|
398
|
+
### Plutus Script Decoder
|
|
399
|
+
|
|
400
|
+
#### `decode_plutus_program_uplc_json(hex: string): ProgramJson`
|
|
401
|
+
|
|
402
|
+
Decodes Plutus script to UPLC AST in JSON format.
|
|
403
|
+
|
|
404
|
+
```typescript
|
|
405
|
+
const program = decode_plutus_program_uplc_json("59012a01000...");
|
|
406
|
+
// Returns: { version: [1,0,0], program: { ... } }
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
#### `decode_plutus_program_pretty_uplc(hex: string): string`
|
|
410
|
+
|
|
411
|
+
Decodes Plutus script to human-readable UPLC.
|
|
412
|
+
|
|
413
|
+
```typescript
|
|
414
|
+
const code = decode_plutus_program_pretty_uplc("59012a01000...");
|
|
415
|
+
// Returns: "(program 1.0.0 (lam x_0 ...))"
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
### Signature Verification
|
|
419
|
+
|
|
420
|
+
#### `check_block_or_tx_signatures(hex: string): CheckSignaturesResult`
|
|
421
|
+
|
|
422
|
+
Verifies all signatures in transaction or block.
|
|
423
|
+
|
|
424
|
+
```typescript
|
|
425
|
+
const result = check_block_or_tx_signatures(txHex);
|
|
426
|
+
// Returns: { valid, results: [{ valid, tx_hash, invalidVkeyWitnesses, invalidCatalystWitnesses }] }
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
### Script Execution
|
|
430
|
+
|
|
431
|
+
#### `execute_tx_scripts(tx_hex: string, utxos: UTxO[], cost_models: CostModels): ExecuteTxScriptsResult`
|
|
432
|
+
|
|
433
|
+
Executes all Plutus scripts in transaction.
|
|
434
|
+
|
|
435
|
+
```typescript
|
|
436
|
+
const result = execute_tx_scripts(txHex, utxos, costModels);
|
|
437
|
+
// Returns execution units, logs, and status for each redeemer
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
## Data Sources
|
|
441
|
+
|
|
442
|
+
To populate the validation context, you'll need to fetch blockchain data from a Cardano indexer or node. Recommended sources:
|
|
443
|
+
|
|
444
|
+
- **[Blockfrost](https://blockfrost.io/)** - Reliable API with generous free tier
|
|
445
|
+
- **[Koios](https://koios.rest/)** - Community-driven API with rich queries
|
|
446
|
+
- **Cardano Node** - Direct access via `cardano-cli` or `cardano-db-sync`
|
|
447
|
+
- **Custom Indexer** - Roll your own using Pallas or similar libraries
|
|
448
|
+
|
|
449
|
+
## Building from Source
|
|
450
|
+
|
|
451
|
+
### Prerequisites
|
|
452
|
+
|
|
453
|
+
- Rust 1.83 or newer
|
|
454
|
+
- `wasm-pack`
|
|
455
|
+
- Node.js and npm
|
|
456
|
+
|
|
457
|
+
### Build Steps
|
|
458
|
+
|
|
459
|
+
```bash
|
|
460
|
+
# Clone the repository
|
|
461
|
+
git clone https://github.com/your-org/cquisitor-lib.git
|
|
462
|
+
cd cquisitor-lib
|
|
463
|
+
|
|
464
|
+
# Build for Node.js
|
|
465
|
+
npm run rust:build-wasm:node
|
|
466
|
+
|
|
467
|
+
# Build for browser
|
|
468
|
+
npm run rust:build-wasm:browser
|
|
469
|
+
|
|
470
|
+
# Build both targets
|
|
471
|
+
npm run build-all
|
|
472
|
+
|
|
473
|
+
# Generate TypeScript definitions
|
|
474
|
+
npm run generate-dts
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
## Type Definitions
|
|
478
|
+
|
|
479
|
+
Full TypeScript type definitions are available in the package and cover all input and output types. The main types include:
|
|
480
|
+
|
|
481
|
+
- `NecessaryInputData` - Required blockchain data for validation
|
|
482
|
+
- `ValidationInputContext` - Complete validation context structure
|
|
483
|
+
- `ValidationResult` - Validation results with errors and warnings
|
|
484
|
+
- `ProtocolParameters` - Cardano protocol parameters
|
|
485
|
+
- And many more detailed types for UTXOs, certificates, governance, etc.
|
|
486
|
+
|
|
487
|
+
See [types/cquisitor_lib.d.ts](./types/cquisitor_lib.d.ts) for the complete type definitions.
|
|
488
|
+
|
|
489
|
+
## Performance
|
|
490
|
+
|
|
491
|
+
Written in Rust and compiled to WebAssembly for near-native performance in browsers and Node.js.
|
|
492
|
+
|
|
493
|
+
## Contributing
|
|
494
|
+
|
|
495
|
+
Contributions are welcome! Please feel free to submit pull requests or open issues for bugs and feature requests.
|
|
496
|
+
|
|
497
|
+
### Development Workflow
|
|
498
|
+
|
|
499
|
+
1. Fork the repository
|
|
500
|
+
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
501
|
+
3. Make your changes
|
|
502
|
+
4. Run tests (`cargo test`)
|
|
503
|
+
5. Commit your changes (`git commit -m 'Add amazing feature'`)
|
|
504
|
+
6. Push to the branch (`git push origin feature/amazing-feature`)
|
|
505
|
+
7. Open a Pull Request
|
|
506
|
+
|
|
507
|
+
## License
|
|
508
|
+
|
|
509
|
+
This project is licensed under the Apache License 2.0 - see the [LICENSE](./LICENSE) file for details.
|
|
510
|
+
|
|
511
|
+
## Acknowledgments
|
|
512
|
+
|
|
513
|
+
This library builds upon the excellent work of the Cardano community, particularly:
|
|
514
|
+
|
|
515
|
+
- [cardano-serialization-lib](https://github.com/Emurgo/cardano-serialization-lib) - For cardano structures deserialization
|
|
516
|
+
- [Pallas](https://github.com/txpipe/pallas) - Cardano primitives
|
|
517
|
+
- [UPLC](https://github.com/aiken-lang/aiken/tree/main/crates/uplc) - Plutus script execution
|
|
518
|
+
- The Cardano Ledger specification team
|
|
519
|
+
|
|
520
|
+
## Support
|
|
521
|
+
|
|
522
|
+
For questions and support:
|
|
523
|
+
|
|
524
|
+
- 📖 Check the [API Documentation](./API_DOCUMENTATION.md)
|
|
525
|
+
- 🐛 Report bugs via [GitHub Issues](https://github.com/cardananium/cquisitor-lib/issues)
|
|
526
|
+
|
|
527
|
+
---
|
|
528
|
+
|
|
529
|
+
Made with ❤️ for the Cardano ecosystem
|
|
530
|
+
|