TxPlan (YAML) transaction building + Plutus + on-chain validation; toolchain & CI modernization#1
Open
matiwinnetou wants to merge 60 commits into
Open
TxPlan (YAML) transaction building + Plutus + on-chain validation; toolchain & CI modernization#1matiwinnetou wants to merge 60 commits into
matiwinnetou wants to merge 60 commits into
Conversation
Bump cardano-client-lib dependency from 0.7.1 to 0.7.2 in core/build.gradle, and update version references in CLAUDE.md and README.md. Verified with :core:test, :core:nativeCompile, and :native-test:test — all passing. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Align local build and docs with CI, which uses the Oracle GraalVM distribution (distribution: 'graalvm'). Update the README install command (25.0.2-graal, which no longer exists, -> 25.0.3-graal) and upstream note, and bump the native-image SDK dependency 25.0.0 -> 25.0.3. Verified with :core:test, :core:nativeCompile, and :native-test:test on Oracle GraalVM 25.0.3 — all passing. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Capture the project's first roadmap: 33 items across wrapper parity, build/CI/distribution, testing, user docs, and a website, each tagged P0/P1/P2. Includes an "Upstream CCL" section noting offline-relevant modules not yet wrapped (CIP-30/CIP-27 available in 0.7.2; txflow, plutus-aiken, crypto-ext, cip102 gated on the unreleased 0.8.0), plus a Non-Goals section (Node.js blocked, backend HTTP and stateful verified-structures out of scope). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the floating java-version '25' with the exact patch '25.0.3' in both workflows so builds are reproducible and match the local toolchain. Check the item off in TODO.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A source-level diff of wrappers/js/src/index.js against the Python reference shows the JS wrapper is feature-complete (mintPlutusAssets, collectFromScript, readFrom, ScriptTxBuilder, compose all present). The earlier "JS feature gap" was wrong. The real gap is test coverage: the JS script/Plutus paths have no integration tests. Move that to the Testing section. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
First slice of the per-wrapper docs/examples work (TODO §4). Adds wrappers/python/README.md plus three runnable, no-DevKit examples: account/key derivation, crypto+address primitives, and an offline QuickTx build+sign. All three verified running against the locally built native lib. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds wrappers/go/README.md plus three runnable, no-DevKit example programs (account, primitives, transaction) under examples/. All three verified running via `go run` against the locally built native lib. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds wrappers/rust/README.md plus three Cargo examples (account, primitives, transaction). All three verified running via `cargo run --example` against the locally built native lib. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds wrappers/js/README.md plus three Bun examples (account, primitives, transaction). API calls cross-checked against src/index.js and mirror the existing passing quicktx integration test. Not executed locally (Bun is not installed on this machine); CI runs Bun and will exercise them. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The CI matrix only installed GraalVM, Bun, and pytest, so the :wrappers:go:test and :wrappers:rust:test gradle Exec tasks failed with "go: command not found" (and cargo would follow). Add actions/setup-go and dtolnay/rust-toolchain so go/cargo are on PATH. Go/Rust DevKit integration tests already skip when no devnet is present, so the wrapper test steps can pass headless. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Go test suite crashes on Linux x86_64 with a GraalVM
StackOverflowError ("yellow zone of the stack did not make any stack
space available") when the shared library is called via cgo, while
macOS passes. Give isolate threads a larger stack to mitigate. Verified
the flag builds and macOS Go tests still pass locally; Linux can only be
checked on CI.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Revert the ineffective -R:StackSize flag. The real cause of the Linux x86_64 Go crash is thread affinity: a GraalVM IsolateThread is bound to its creating OS thread, but Go migrates goroutines across OS threads, so calls from another thread read a bogus stack boundary and the isolate raises a "yellow zone" StackOverflowError. macOS is unaffected. Mark the Linux Go step continue-on-error so CI is not blocked, document the root cause and the proper wrapper-level fix (runtime.LockOSThread / attach-detach) in TODO.md and the Go README. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Route all FFI calls through a single dedicated OS thread that owns the GraalVM isolate for the Bridge's lifetime. A goroutine running a cgo call can be migrated by the Go scheduler to a different OS thread than the one that created the isolate; GraalVM then reads the wrong thread's stack and crashes on Linux x86_64 with a "yellow zone" StackOverflowError. New() starts a goroutine that runtime.LockOSThread()s, creates the isolate there, and serves queued FFI closures from a channel. All API methods submit their C call (and the per-thread result/error fetch) via invoke/invokeRC so call + result retrieval happen on that one thread. go vet + full Go test suite pass locally on macOS. Removes the temporary continue-on-error so Linux CI now validates the fix for real. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a Windows job to CI that builds the native library and runs the JVM tests, validating the Windows native-image build (the README advertises libccl.dll but it was never built). Add windows-x86_64 to the release matrix, including the libccl.lib import library that native-image emits on Windows for linking against the DLL. Wrapper test coverage on Windows (Go cgo, C Makefile, etc.) is a separate follow-up tracked in TODO.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add an integration-tests workflow (PR to main + manual dispatch) that installs Yaci DevKit via npm, starts a local Cardano devnet (admin API on :10000), and runs every wrapper's integration suite against it — the real build -> sign -> submit round trips that previously never ran in CI. Add integrationTest gradle tasks for the Python and JS wrappers (whose plain test tasks exclude integration); Go and Rust test tasks already include their integration tests, which skip when DevKit is down and run when it is up. Verified locally that the full suites skip integration cleanly without a devnet. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Temporary diagnostic to inspect whether DevKit's /epochs/parameters includes the Conway gov_action_deposit / drep_deposit fields, which the governance/DRep build paths require (their absence NPEs the build). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Yaci DevKit's admin /epochs/parameters returns null for every Conway governance parameter (gov_action_deposit, drep_deposit, lifetimes). Building a governance proposal or DRep registration reads the deposit and throws NullPointerException on the null value — the cause of the 9-test governance/DRep failures in the DevKit integration run. YaciProtocolParamsSupplier now fills the standard devnet defaults (gov_action_deposit=1000 ADA, drep_deposit=2 ADA, lifetimes) when the provider returns null, so proposal/DRep tx building works. Verified at the JVM level that proposal/DRep builds succeed when these are present. Also removes the temporary params-dump debug step. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
With the gov deposit now correctly applied, the proposal builds need more than the previous 500 ADA topup. Raise fund_account's default to 2000 ADA to cover the 1000 ADA governance action deposit plus fees. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
PoolRegistration.serialize() expects the reward account as hex-encoded address bytes, but the bridge passed the bech32 stake address, so pool registration failed with CborSerializationException. Convert bech32 stake/base addresses to hex bytes in buildPoolRegistration. Verified at the JVM level that register_pool now builds. Also make the Python DevKit helper's submit_tx include the node's HTTP error body in the raised exception, so submit rejections (the remaining attach_native_script / delegate_voting_power 400s) report why. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Three test-level fixes for the last DevKit submit failures (diagnosed via the node's rejection bodies): - hard_fork_initiation: proposed protocol v10.0 which cannot follow the devnet's current v10.2 (ProposalCantFollow). Propose v11.0. - attach_native_script: attached a native script nothing consumed (ExtraneousScriptWitnessesUTXOW). Mint a token under the sig script instead — its key hash is the sender's payment key, so the existing signature satisfies it. - delegate_voting_power: the vote-delegation cert needs the stake key to witness it (MissingVKeyWitnessesUTXOW), but sign_tx signs with the payment key only. Make the test build-only and track exposing stake-key signing (Account.signWithStakeKey) in TODO.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The JS new-features integration suite has the same governance tests as Python and hit the same failures against DevKit: proposals under-funded (500 ADA topup vs 1000 ADA deposit) and hard_fork proposing v10.0 which cannot follow the devnet's v10.2. Bump fundAccount default to 2000 ADA and propose v11.0. (attach_native_script and delegate_voting_power already pass in the JS suite.) Note: these tests were not hanging earlier — a full four-wrapper DevKit run just takes ~25-30 min as each test waits on real block production. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Capture the developer-experience improvements discussed (esp. for Go): static linking (libccl.a) for single self-contained binaries, musl/Alpine builds, runtime lib<->wrapper version check, release artifact signing, a CGO_ENABLED=0 guard, an end-to-end build->sign->submit example, and CI status badges. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Document every @centrypoint class with class- and method-level Javadoc: CclBridge (lifecycle + the calling convention), ErrorCodes, and the api/* namespaces (Account, Address, Crypto, Transaction, Plutus, Script, Governance, Wallet, QuickTx). Each method documents its exported C name, parameters, the JSON/hex result contract retrieved via ccl_get_result, and the status codes it can return. No behavior change. Verified with :core:compileJava and :core:javadoc (HTML generated cleanly). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…suppliers) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Upgrade CCL 0.7.2 -> 0.8.0-pre4 (backward compatible; only the deprecated
ScriptTx path changes) and adopt CCL's native TxPlan YAML format.
- Delete the bespoke spec + mappers + provider path (~2400 LOC):
TxSpec, TxOperation, TxItemSpec, TxSpecMapper, ScriptTxSpecMapper,
ProviderConfig, Yaci{Utxo,ProtocolParams}Supplier, YaciTransactionEvaluator.
- Rewrite QuickTxService to: TxPlan.from(yaml) -> QuickTxBuilder(static
utxoSupplier, () -> protocolParams, null) -> compose(plan) -> build()
-> CBOR. Fully offline, never submits. Reuses StaticUtxoSupplier.
- New entrypoint signature: ccl_quicktx_build(thread, yaml, utxos_json,
protocol_params_json); result stays {tx_cbor, tx_hash, fee} JSON.
- Add --initialize-at-build-time=org.yaml.snakeyaml for native-image.
- Rewrite QuickTxApiTest to build TxPlan YAML txs offline (payments,
multi-intent, variable substitution, insufficient-funds).
Plutus script txs are deferred (no offline exec-unit evaluator in pre4).
Wrappers still target the old signature and are updated next.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Last wrapper. Delete the ~1300-line fluent builder from index.js (TxBuilder/ScriptTxBuilder/ComposeTxBuilder/Amount/etc.) and the provider module; QuickTxApi.build(yaml, utxos, protocolParams) calls the 3-arg ccl_quicktx_build and parses the YAML result via the `yaml` package. - index.js: ccl_quicktx_build FFI -> 3 cstrings; drop provider export. - package.json: add `yaml` dependency. - index.d.ts: replace builder/provider types with the thin QuickTxApi. - tests: ccl.test.js QuickTx tests + quicktx.integration.test.js rewritten to YAML; delete provider/compose/new-features integration tests. - example + README updated to the YAML API. Verified: bun test green (47 pass / 0 fail; integration skips without DevKit); `bun examples/transaction.js` round-trips YAML in -> out. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
PRs into develop (e.g. the TxPlan refactor) got no CI because the workflows only triggered on main. Add develop to both the unit CI and the DevKit integration-tests triggers so feature->develop PRs run the full matrix. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The doc described the deleted bespoke JSON spec. Rewrite it for the TxPlan YAML flow: the new ccl_quicktx_build(yaml, utxos, protocol_params) signature, the YAML result, the TxPlan document structure, the real intent `type` discriminators, verified payment/variable examples, the caller-supplied UTXO/protocol-params JSON, and per-wrapper build+sign snippets. Notes provider removal and the deferred Plutus path. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The first full PR run went red: Python tests failed with ModuleNotFoundError: yaml, and the JS tests with Cannot find package 'yaml' — CI never installed the YAML parsers the wrappers gained in this refactor. - ci.yml + integration-tests.yml: pip install pyyaml alongside pytest. - wrappers/js/build.gradle: `bun install` before `bun test` (unit + integration) so the `yaml` package is present. Go (yaml.v3) and Rust (serde_yaml) are fetched automatically by go test / cargo test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The metadata intent's value is a scalar string the deserializer
auto-detects; passing it as a JSON string ('{"674": {...}}') is the
working shape (the earlier nested-map attempt threw a YAML parse error).
- QuickTxApiTest: add paymentWithMetadata — builds a payment+metadata
TxPlan and asserts the tx body carries an auxiliary data hash, i.e.
the metadata is actually attached (not just parsed). Confirmed in the
native lib too (reflect-config already covers the metadata classes).
- docs/quicktx.md: add the verified metadata YAML example.
Closes the deferred metadata follow-up.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Plutus spends/mints need each redeemer's execution units (mem + CPU steps), which requires running the script in a UPLC evaluator. Rather than embed an evaluator, the bridge takes the units as a fourth caller-supplied input — exactly like UTXOs and protocol parameters — and wires CCL's StaticTransactionEvaluator to stamp them onto the redeemers, fully offline. The caller computes them with whatever they like (Ogmios, Blockfrost, Aiken, Scalus). See TODO §2b for the planned pick-and-choose evaluator helpers/examples. - core: QuickTxService.buildTransaction gains exec_units_json -> List<ExUnits> -> withTxEvaluator(StaticTransactionEvaluator); ccl_quicktx_build entrypoint is now 4-arg (yaml, utxos, protocol_params, exec_units). - native-image: register the Plutus reflection that Jackson needs — RedeemerTag / PlutusVersion enums (their @JsonProperty string forms), the plutus.spec types, and the plutus.spec.serializers (custom PlutusData ser/deser). Without these a script build fails in the native image though it passes on the JVM. - wrappers: optional 4th arg through all four — Python/JS default param, Go variadic, Rust Option<&Value>. Existing 3-arg calls unchanged (Go/JS/Python); Rust call sites pass None. - tests: QuickTxApiTest builds a real Plutus mint (always-succeeds V2 policy) offline and asserts the redeemer carries the supplied units, and that it fails without them; Python wrapper has the same pair. Verified end-to-end in the native lib (build OK with units, -10 without). - docs/quicktx.md + TODO.md updated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Restores the coverage dropped in the builder->TxPlan migration, where it matters most: the native + wrapper path (the JVM/TxPlan layer is CCL's own, covered upstream). - QuickTxIntentsTest (JVM): builds each op with CCL, serializes via TxPlan.from(tx).toYaml(), builds it through the bridge, and emits the exact YAML to build/intent-yamls/<name>.yaml as a fixture. Covers stake_registration/deregistration/delegation/withdrawal, donation, drep_registration/deregistration/update, voting, voting_delegation, governance_proposal (11). - wrappers/go/ccl/intents_test.go: table-driven test that drives every testdata/intents/*.yaml fixture through the native library via the Go wrapper, asserting tx_cbor/tx_hash/fee. This is the real bridge check — it confirms the native-image reflection config covers the governance/ staking/DRep classes (it does; these intents serialize to string fields). 11/11 pass end-to-end in the native lib. Pools + Plutus spend next. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
pool_registration / pool_update / pool_retirement added to the intent fixtures and Go E2E. Pool registration surfaced native-image reflection gaps the JVM test cannot — exactly what the Go E2E is for: - util.serializers (HexToByteArrayDeserializer / ByteArrayToHexSerializer / InetAddress*) for the byte-array + relay-IP fields, and - transaction.spec.cert.* + spec.UnitInterval for the certificate / margin types. All 14 intent fixtures now build end-to-end through the native lib via Go. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A Plutus spend collects from a script-address UTXO with a redeemer + datum and attaches the spending validator. QuickTxIntentsTest builds it and emits the fixture; script_spend_test.go drives it through the native lib with the script UTXO (+ datum hash), a fee/collateral UTXO, and the caller-supplied execution units — asserting it builds with units and fails without. Reuses the Plutus reflection config from the mint (no new native config needed). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds the last intent types to the fixtures + Go end-to-end table: native `minting` (NativeScript policy), `native_script` attachment, `collect_from` (explicit input selection), and `reference_input` (read-only inputs). The Go table now supplies a second small UTXO for the reference-input fixture to read. Every TxPlan intent type is now exercised end-to-end through the native library via Go (18 in the table + Plutus spend + the payment/metadata/ mint cases elsewhere). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds script_minting to the fixtures + a Go E2E test (build with exec units, fail without), mirroring the spend. Go now exercises every TxPlan intent type end-to-end through the native library. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds a metadata fixture (payment + attached CIP-20 metadata) to the Go E2E table. Every TxPlan intent type is now exercised end-to-end through the native library via Go. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…tures
Brings the per-intent native end-to-end coverage that Go had to every
wrapper, so each language proves it builds all TxPlan intents through the
native library.
- test-fixtures/quicktx-intents/: shared, version-controlled fixtures
(19 generic intents + plutus/{script_minting,script_collect_from}),
generated by the JVM QuickTxIntentsTest. Single source of truth.
- Go: repointed intents_test.go / script_spend_test.go at the shared dir;
dropped the duplicated wrappers/go/ccl/testdata copies.
- Python (test_quicktx_intents.py), Rust (intents_test.rs), JS
(intents.e2e.test.js): table-driven tests over the shared fixtures +
dedicated Plutus mint/spend tests (build with exec units, fail without).
- JS gradle test task now also runs intents.e2e.test.js.
All four wrappers: every intent type builds end-to-end. No native changes
needed — the reflection config proven by the Go suite already covers it.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The bridge has been on 0.8.0-pre4 since the TxPlan refactor, but README, CLAUDE.md, and TODO.md still said 0.7.2. Mark the 0.7.2->0.8.0 upgrade item done and re-frame TODO §6 (the upstream modules are all available on the current dependency now). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Compose was a feature of the old bespoke format that the TxPlan migration left untested. TxPlan's `transaction` list supports it natively (multiple `tx` entries, each with its own `from`, one fee_payer). - QuickTxIntentsTest.compose builds a 2-sender compose via TxPlan.from(List<AbstractTx>).toYaml() and emits the compose.yaml fixture. - All four wrapper intent tables pick it up; each supplies a second sender's UTXO so the compose builds end-to-end through the native lib. - docs/quicktx.md gets a compose example. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Governance/staking intents build offline but couldn't be submitted: their certificates must be witnessed by the stake (or DRep) key, while ccl_account_sign_tx adds only the payment key — the node rejects them with MissingVKeyWitnessesUTXOW. - core: new ccl_account_sign_tx_multi(..., keys) signs with any subset of payment/stake/drep/committee_cold/committee_hot (CCL Account.signWith*Key), applied in order. The original ccl_account_sign_tx is unchanged. - wrappers: sign_tx_with_keys (Python/Rust), SignTxWithKeys (Go, variadic roles), signTxWithKeys (JS); keys as a list/CSV. - tests: Go asserts payment+stake adds a witness vs payment-only and that an unknown role errors; Python has the parity test. Rust/JS bindings verified to compile + load. - TODO.md marks the item done; docs/quicktx.md documents it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Converts "builds offline" into "a real node accepts it" for the straightforward intents: stake_registration, drep_registration, donation, governance info proposal, metadata, and Plutus mint. Each resets the devnet, funds the fixed test account, builds the intent's fixture with its real UTXOs, signs with the required key roles (e.g. payment+stake for staking, payment+drep for DRep, payment for the rest), submits, and asserts the tx is retrievable on-chain. Skips when DevKit is not running, so it runs only in the CI "Integration Tests (DevKit)" job. Native mint (no-key policy) and Plutus spend (lock-then-spend) follow once this batch confirms the pattern on CI. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
First CI run surfaced real issues (all fixable): - stake_registration / metadata / Plutus mint already submitted fine; the on-chain check used a garbled hash (the devnet returns a chunked body, so devkitSubmitTx's "hash" was the chunk-size prefix). Verify via submit success (HTTP 200/202 = the node validated + accepted the tx) instead. - donation: the Conway cert asserts the stated treasury equals the chain's; regenerate the fixture with currentTreasuryValue=0 (fresh devnet). - drep_registration / governance_proposal: DevKit's /epochs/parameters omits drep_deposit / gov_action_deposit; inject them so the build can compute the certificate deposits (the node validates them on submit). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
drep_registration / governance_proposal still failed: DevKit's /epochs/parameters returns drep_deposit and gov_action_deposit as null (present, not absent), so the if-absent guard skipped the injection. Set them unconditionally so the build can compute the certificate deposits; the node validates the values on submit. (stake_registration, metadata, Plutus mint, donation now pass on-chain.) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5/6 now pass on-chain. The proposal failed with ProposalReturnAccountDoesNotExist: a Conway proposal's deposit-return account must be a registered stake address. Register it first, then submit the proposal in the next block. Refactor: extract devnetPP() (params + Conway deposits) and signSubmit() (build->sign->submit) so the proposal can run two sequential txs on one devnet. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The minting fixture used a random policy key, so the account couldn't sign it for submission. Regenerate it under an empty ScriptAll policy (script_hex 820180) that requires no signature, and add TestIntegrationNativeMint which the fee payer alone submits. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds a plutus_lock fixture (payToContract: pays a UTXO to the always-succeeds script address carrying the datum hash) and TestIntegrationPlutusSpend, which: 1. locks 10 ADA at the script address, 2. finds the locked UTXO on-chain, 3. repoints the script_collect_from fixture's utxo_ref at it, and 4. spends it with the caller-supplied execution units. Completes the 8 straightforward submit-tests (the other 6 + native mint are green on-chain). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds a submit-test per remaining concern, doing the on-chain setup each
certificate requires (sequenced txs on one devnet):
- voting_delegation : register stake -> delegate voting power (to abstain)
- drep_update : register DRep -> update DRep
- drep_deregistration : register DRep -> deregister DRep
- stake_withdrawal : register stake -> withdraw (zero) rewards
- stake_delegation : repoint the fixture at a real devnet pool, register+delegate
- voting : register DRep + stake -> submit info proposal (its build
tx hash is the gov action id) -> vote on it
- pool_registration : key the pool to the account's stake key (operator/owner/
reward account) so the stake-key signature witnesses it;
register the reward stake address first
Also inject pool_deposit (DevKit returns it null). Blind, CI-verified.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fixes (from the last run's ledger errors): - stake_withdrawal: Conway requires the stake address to be vote-delegated before it can withdraw, so register stake -> delegate voting -> withdraw. - stake_delegation: DevKit exposes no pool-list endpoint (/pools 404), so register a pool keyed to the account and delegate to it (the fixture is now delegate-only; the pool id is captured from StakePoolId). Depth (turn "node accepted" into "verifiably did the thing"): - native mint / Plutus mint now assert the minted asset is present at the receiver (assertMintedAssetAt). - Plutus spend asserts the locked script UTXO was actually consumed. - TestIntegrationDRepKeyRequired: a DRep registration signed with the payment key only must be rejected by the node, proving the extra sign_tx_with_keys witness is genuinely required. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace bespoke JSON tx-spec with CCL TxPlan (YAML): offline build, Plutus, full intent coverage
The native lib is offline by design — the caller supplies UTXOs, protocol params, and (for Plutus) exec units, and every wrapper is a pure pass-through that fetches none of them. Add §2c (P1) for optional, per-wrapper provider helpers that fetch UTXOs + protocol params via each language's own HTTP client and feed them into the offline build() — the sibling of §2b (exec units). Also reconcile the WISHLIST-vs-Non-Goals tension: a provider baked into libccl stays excluded, but wrapper-side convenience helpers are explicitly in scope. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Brings
developtomain. Two bodies of work have accumulated since the last release: (A) toolchain/CI/docs modernization that got CI green and added developer docs, and (B) a large refactor that replaces the bespoke JSON transaction format with CCL's native TxPlan (YAML), adds Plutus support, and validates the whole intent surface against a real Cardano node.Net: ≈−11,300 lines across ~113 files (59 commits) — the bespoke tx-spec, its mappers, the provider path, and the four per-language fluent builders are gone.
This release changes the transaction-building contract end to end. Any code on the old JSON-operations API must migrate.
main)ccl_quicktx_build(thread, specJson)— one bespoke JSON specccl_quicktx_build(thread, yaml, utxos_json, protocol_params_json, exec_units_json)TxBuilder/ScriptTxBuilder(.payToAddress(...).build()) +ProviderConfigbuild(yaml, utxos, protocolParams, execUnits?)— pass a TxPlan YAML string + caller-supplied chain datautxos,protocolParams); no provider/HTTP path{tx_cbor, tx_hash, fee}{tx_cbor, tx_hash, fee}ccl_account_sign_txis payment-only and unchanged; stake/DRep/committee certs now require the newsign_tx_with_keys(..., ["payment","stake"])or they're rejected withMissingVKeyWitnessesUTXOWNew wrapper runtime dependencies (a YAML parser per wrapper): Python
pyyaml>=6.0· Gogopkg.in/yaml.v3· Rustserde_yaml 0.9· JSyaml ^2.3.0.Part A — Toolchain, CI & docs
25.0.3— align local build + docs with CI'sdistribution: 'graalvm'; pin CI/release to the exact patch (was floating'25') for reproducibility.actions/setup-go+dtolnay/rust-toolchain(the matrix lacked Go/Rust, so those tasks failed withcommand not found); this got macOS green.StackOverflowError(a goroutine migrating off the OS thread that created the isolate). All FFI calls now run on one dedicated OS thread (runtime.LockOSThread+ an executor goroutine) for theBridge's lifetime.libccl.dllon Windows — new CI Windows job + awindows-x86_64release artifact (DLL + import library + headers).integration-tests.ymlstarts Yaci DevKit (admin API:10000) and runs the wrappers' integration suites (real build → sign → submit). (First introduced here; now green — see Part B.)TODO.mdbacklog (incl. an upstream-CCL scan and a Non-Goals section). CI also now runs on PRs intodevelop.Part B — TxPlan (YAML) transaction building
0.7.2→0.8.0-pre4— backward-compatible for the bridge; only the deprecated ScriptTx path changes.ccl_quicktx_build(thread, yaml, utxos_json, protocol_params_json, exec_units_json)builds fully offline from a TxPlan YAML document with caller-supplied chain data; the result{tx_cbor, tx_hash, fee}is YAML.StaticTransactionEvaluatorto stamp them on (it never runs the script). Includes the native-image reflection registration the Plutus/cert/serializer classes need.ccl_account_sign_tx_multi(…, keys)signs with any subset ofpayment/stake/drep/committee_cold/committee_hot, fixingMissingVKeyWitnessesUTXOWfor stake/vote/DRep certs (the original payment-onlyccl_account_sign_txis unchanged).build(yaml, utxos, protocolParams, execUnits?)+sign_tx_with_keys.test-fixtures/quicktx-intents/, generated by the JVM from CCL's exact intent shapes) driven through the native library in Go, Python, Rust, JS: payments, metadata, native mint, donation, staking, DRep, voting, governance proposals, pools, native scripts, reference/explicit inputs, compose (multi-sender), and both Plutus paths.Verification
:core:test+:core:nativeCompile+:native-test:testgreen on Oracle GraalVM 25.0.3.Known limitations / follow-ups (tracked in
TODO.md, not blockers)