You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Pin canton-lib v0.11.0 for Canton 3.6.1 and release 0.9.0 - #94
Old behavior
cbtc-lib pins canton-lib v0.9.0. That version sends the filter and verbose fields in every active-contracts request. Canton 3.6.1 rejects both fields with DEPRECATED_API_DISABLED.
The effect of that rejection depends on the path the query takes:
Websocket queries, such as cbtc::active_contracts::get and the cbtc-tui balance query. canton-lib v0.9.0 reads the error message as a stream with no contracts and returns an empty result. Nothing logs an error. On devnet, a balance check reported 0 for a party that holds 4 holdings.
Mint and redeem. They call the HTTP function ledger::active_contracts::get_by_party, and it returns an error. So mint and redeem fail with post_v2_state_active_contracts failed: ....
The Security workflow also fails on every PR and on main.
New behavior
cbtc-lib pins canton-lib v0.11.0, the latest release. That release includes these changes:
v0.10.0 sends eventFormat instead of the disabled fields, so the participant accepts the queries again.
v0.10.1 returns the Ledger API's error when a participant rejects a websocket query. That query now fails with Err("Ledger API returned <code>: <cause>") instead of returning an empty result. The HTTP path keeps its post_v2_state_active_contracts failed text.
v0.11.0 moves canton-api-client to 3.6.1, which is generated from the Canton 3.6.1 OpenAPI spec.
Cargo Deny passes. The Cargo Audit job is removed.
Verification
I ran the check_balance example on devnet. All devnet participants run Splice 0.9.0, which ships Canton 3.6.1. Both builds queried the same party with the same credentials:
Build
canton-lib
Exit
Result
main (be95c7f)
v0.9.0
0
0 holdings, balance 0
This PR (763bcc3)
v0.11.0
0
4 holdings, 20.1751930825 CBTC
cargo clippy --workspace --all-targets -- -D warnings passes on the pinned rustc 1.94.1.
cargo test --workspace --all-targets passes on rustc 1.94.1: 98 passed, 0 failed, 6 ignored.
parses_and_aggregates_party_rights passes. It checks that cbtc-tui reads the act and read rights from the new client's Kind variants.
I ran the cbtc-tui login code on devnet with a temporary test, which I did not commit. The test imports the profile from a .env file, logs in to Keycloak and calls fetch_parties. Both builds used the same user:
Build
Client
Rights from ledger
Parties parsed
Flags
main (be95c7f)
3.6.0
4
2
act=true, read=true for both
This PR (763bcc3)
3.6.1
4
2
act=true, read=true for both
The 4 rights are 2 act-as rights and 2 read-as rights. If the PR matched the wrong Kind variant, both parties would show read=false.
Cargo.lock holds one entry each for common, ledger, token, keycloak, registry and canton-api-client. The canton-lib crates are at v0.11.0 (87646b7), and the client is at 3.6.1-0.1.0. So no second copy of canton-lib or of the client is built.
Cargo Deny passes in CI on 2e6bbac. Both Socket Security checks pass too.
I did not run the 6 ignored live tests. The devnet runs check read-only calls. They do not check mint, redeem, a transfer or the cbtc-tui screens.
The change that enables it
The five canton-lib pins in Cargo.toml and the two in cbtc-tui/Cargo.toml move from v0.9.0 to v0.11.0.
canton-api-client moves from 3.6.0-0.1.0 to 3.6.1-0.1.0 in both manifests.
parse_party_rights in cbtc-tui/src/session.rs matches Kind::KindOneOf4 for CanReadAs, not KindOneOf3. This is the only Rust change.
The crate version goes from 0.8.0 to 0.9.0. The CHANGELOG and README name the new versions.
The README "Get Active Contracts" curl example sends eventFormat instead of the disabled top-level fields. It also expands $SENDER_PARTY_ID, which it sent as literal text before.
h2 goes from 0.4.12 to 0.4.19 in Cargo.lock.
The cargo-audit job is removed from .github/workflows/security.yml.
The release is breaking for a consumer that also pins canton-lib or canton-api-client. That consumer must move its canton-lib pin to v0.11.0 and its client to 3.6.1-0.1.0 in the same change.
A consumer that matches on Kind variants by number must check them. Client 3.6.1 moves every variant after KindOneOf up by one.
This release is tested on Canton 3.6.1 only. The participant's error says that Canton deprecated the old fields in 3.4, which suggests that eventFormat works from 3.4. Nobody has tested a TestNet or MainNet participant yet, and the CHANGELOG says so.
Each service that uses cbtc-lib needs its own bump to v0.9.0. The DevNet participants already run 3.6.1, so a DevNet service that has not been bumped now reads empty balances, and its mint and redeem calls fail. The later upgrades are TestNet on 2026-10-28 and MainNet on 2026-11-07.
Details
Why v0.11.0 and not v0.10.1
canton-lib released v0.11.0 on 2026-10-08, before this PR merged. If cbtc-lib released on v0.10.1, every service would need a second breaking bump soon after. Each canton-lib tag is a separate Cargo source, so a service cannot mix cbtc 0.9.0 on v0.10.1 with its own pin on v0.11.0.
Why the client pin moves
ledger re-exports canton_api_client::models, and cbtc uses both paths. For example, src/mint_redeem/models.rs imports JsActiveContract from the client, and redeem.rs imports it from ledger::models. Two client versions make these two different types, and the build fails. The old requirement 3.6.0-0.1.0 is a pre-release version, so Cargo does not match it to 3.6.1-0.1.0.
Why the Kind variant changes
Client 3.6.1 adds the CanActAsAnyParty user right. The OpenAPI generator numbers the variants of Kind in order:
Right
Client 3.6.0
Client 3.6.1
CanActAs
KindOneOf
KindOneOf
CanActAsAnyParty
none
KindOneOf1
CanReadAs
KindOneOf3
KindOneOf4
In client 3.6.1, KindOneOf3 is CanExecuteAsAnyParty, so the old code does not compile.
Why the Cargo Audit job goes
The job fails before it checks a single dependency:
The rustsec/audit-check@v2.0.0 action compiles cargo-audit from source on every run.
The action builds it without --locked, so Cargo picks the newest dependency versions.
One of them, kstring 2.0.5, needs rustc 1.96.0. This repo pins rustc 1.94.1.
The Security run on main at be95c7f shows the error: "rustc 1.94.1 is not supported by the following package: kstring@2.0.5 requires rustc 1.96.0".
The advisory coverage stays the same. Cargo Deny reads the same RustSec database, and it installs a prebuilt binary, so the rustc pin does not affect it. canton-lib removed the same job for the same reason in DLC-link/canton-lib#61.
You can keep cargo-audit as a second check instead. There are two ways to do that, and each belongs in its own PR:
Install a prebuilt cargo-audit, or build it on a newer toolchain inside the job.
Raise the rustc pin to 1.96.
Why 0.9.0 and not 0.8.1
cbtc's own API does not change. But cbtc re-exports common types such as DamlDecimal, and common moves from 0.9.0 to 0.11.0. cbtc's public functions also take ledger::models types, such as from_active_contract. Under 0.x SemVer, these are breaking upgrades of public dependencies. A consumer that pins canton-lib v0.9.0 next to cbtc 0.9.0 gets two common packages, and its code stops compiling.
Why both manifests move
cbtc-tui pins canton-lib separately. If only the root manifest moves, the TUI keeps canton-lib v0.9.0 and reads empty results on 3.6.1.
Security
h2 0.4.12 carries RUSTSEC-2026-0258, which made Cargo Deny fail. 0.4.19 is the version that canton-lib v0.11.0 locks. This lockfile sets the version for cbtc-tui and the examples only. A consumer's own lockfile sets it for that consumer.
Commits
Pin canton-lib v0.10.0 and release 0.9.0.
Move h2 to 0.4.19 for RUSTSEC-2026-0258.
Remove the Cargo Audit job from Security.
Pin canton-lib v0.10.1.
Date the 0.9.0 release 2026-10-08.
Pin canton-lib v0.11.0 and canton-api-client 3.6.1.
The branch name still says 0.10.0, but the PR pins v0.11.0.
After merge
Tag the merge commit v0.9.0 and publish the release. The CHANGELOG dates the release 2026-10-08. If the merge happens on another day, change that date first.
Canton 3.6.1 rejects the top-level filter and verbose fields of an
active-contracts request with DEPRECATED_API_DISABLED. canton-lib
0.9.0 sends both. 0.10.0 sends eventFormat instead, so mint, redeem,
active_contracts::get and the cbtc-tui queries keep working once a
participant upgrades. No code in this crate changes.
The five canton-lib pins and cbtc-tui's two move together, so the
lockfile keeps one copy of common.
The release is breaking. cbtc re-exports common types, and common
moves from 0.9.0 to 0.10.0, so a consumer that also pins canton-lib
must move to v0.10.0.
Refs DLC-link/canton-lib#61
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
h2 0.4.12 carries RUSTSEC-2026-0258, so Cargo Deny fails on every
PR and on main. 0.4.19 is the version canton-lib 0.10.0 locks.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
rustsec/audit-check builds cargo-audit from source without --locked.
That pulls kstring 2.0.5, which needs rustc 1.96, and this repo pins
1.94.1. The job fails before it checks anything, on every PR.
Cargo Deny reads the same RustSec database and stays, so the
advisory check keeps its coverage. canton-lib removed the same job
for the same reason.
Refs DLC-link/canton-lib#61
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
canton-lib 0.10.1 returns the Ledger API's error when a participant
rejects a query. 0.10.0 and earlier returned an empty result, so a
rejected query read as "no contracts". Releasing cbtc-lib 0.9.0 on
0.10.1 gives consumers the 3.6.1 request format and this fix in one
bump.
All seven pins move together, and Cargo.lock keeps one entry for each
canton-lib crate.
Refs DLC-link/canton-lib#62
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gyorgybalazsi
changed the title
Pin canton-lib v0.10.0 for Canton 3.6.1 and release 0.9.0
Pin canton-lib v0.10.1 for Canton 3.6.1 and release 0.9.0
Oct 7, 2026
The one finding. Copilot's overview says: "The changelog assigns the release a future date." It left no inline comment.
Won't fix. The date is deliberate. The release is planned for 2026-10-08, so the CHANGELOG heading [0.9.0] - 2026-10-08 names that day. If the merge happens on another day, change the date before the tag.
Outcome: the loop converged in round 1. Copilot listed no other findings. No items are open.
canton-lib v0.11.0 moves canton-api-client to 3.6.1, and ledger
re-exports the client's models. The client pin moves in both manifests
too, so that ledger::models and cbtc's own client types are one type.
Client 3.6.1 adds CanActAsAnyParty as Kind::KindOneOf1, so CanReadAs
moves from KindOneOf3 to KindOneOf4. parse_party_rights in cbtc-tui
matches the new variant.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gyorgybalazsi
changed the title
Pin canton-lib v0.10.1 for Canton 3.6.1 and release 0.9.0
Pin canton-lib v0.11.0 for Canton 3.6.1 and release 0.9.0
Oct 8, 2026
Round 2 reviewed the move to canton-lib v0.11.0 and canton-api-client 3.6.1. Copilot left 0 findings. Its verdict asks a human to look at two points. The PR body names both as caveats:
Live ledger operations. I ran one read-only query on devnet. I did not run mint, redeem, a transfer or the cbtc-tui login.
Security coverage. This PR removes the Cargo Audit job. Cargo Deny reads the same RustSec database and passes.
Round 1 remark about the future CHANGELOG date no longer applies. Today is 2026-10-08, which is the release date in the CHANGELOG.
Outcome: converged. Open items: none. The PR needs a human approval.
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this PR. The canton-lib bump looks correct. I built the workspace and ran the tests at 546df4d on rustc 1.94.1: 98 passed, 0 failed, 6 ignored. Every cbtc caller of the changed canton-lib functions passes the new error up with ?, so no path turns a rejected query into a zero balance.
I keep the h2 0.4.19 bump in this PR. Three findings follow. None of them blocks the merge.
Documentation
OPS-03 · Decision · The README curl example still sends filter and verbose
Colour: yellow (fix or defer)
The README has a reference section that shows raw Ledger API calls with curl. Its "Get Active Contracts" example still sends the top-level filter and verbose fields. Canton 3.6.1 rejects exactly these fields with DEPRECATED_API_DISABLED. That rejection is the reason for this release.
The PR edits README.md, but only the version strings. It does not touch this example. So a reader who copies the command against a 3.6.1 participant gets an error. The README then contradicts the CHANGELOG entry of the same release.
Rewrite the body with eventFormat, and move filtersByParty and verbose inside it. The "Accept Transfer" example in the same README already uses eventFormat.
Add a note that the example applies only to Canton before 3.6.
COR-01 · The CHANGELOG says mint and redeem returned empty results, but they returned an error
Colour: green (note)
The CHANGELOG entry says that every active-contracts query returned an empty result and no error on Canton 3.6.1. That is true only for the queries that canton-lib sends over a websocket. These are cbtc::active_contracts::get, the offer queries, and the cbtc-tui balance and offer queries.
Mint and redeem use a different path. They call the HTTP function ledger::active_contracts::get_by_party. In canton-lib v0.9.0, that function already returned Err("post_v2_state_active_contracts failed: ...") on a rejected request. So mint and redeem failed with an error. They did not return empty results.
The new error text has the same limit. Only the websocket functions return Ledger API returned <code>: <cause>. The HTTP path keeps its old text. No code is wrong, but a service owner who reads the entry may search for the wrong error.
Anchor:CHANGELOG.md, 0.9.0 entry:
So on a 3.6.1 participant, every active-contracts query in this crate
returned an empty result and no error. Mint, redeem,
`cbtc::active_contracts::get` and the `cbtc-tui` queries are affected.
Fix: Change the paragraph. Say that the websocket reads returned empty results. Say that mint and redeem use HTTP and failed with an error. The PR body makes the same claim.
The doc comments in src/mint_redeem/redeem.rs say that list_holdings opens a websocket, but it calls HTTP get_by_party. These comments are older than this PR and are a likely source of the error. A separate docs PR can correct them.
Configuration
OPS-01 · The CHANGELOG does not say which Canton versions 0.9.0 supports
Colour: green (note, near threshold)
The CHANGELOG says the release works on Canton 3.6.1. It does not say whether it works on older Canton versions. DevNet participants already run 3.6.1. TestNet upgrades on 2026-10-28 and MainNet on 2026-11-07.
A service owner on TestNet or MainNet must decide when to bump to cbtc 0.9.0. The CHANGELOG gives no answer, so the owner may bump too early or wait too long. I could not test an older participant, so this risk is not confirmed.
The error name gives a hint. DEPRECATED_API_DISABLED means that Canton deprecated the old fields before 3.6.1, so eventFormat probably works on earlier versions. Nobody has tested that on a TestNet or MainNet participant yet.
Anchor:CHANGELOG.md, 0.9.0 entry:
`canton-lib` 0.10.1 fixes that too. A query that the Ledger API rejects now
returns `Err("Ledger API returned <code>: <cause>")`.
Fix: Run one query with this build against a TestNet participant before its upgrade. Then add one sentence to the CHANGELOG. Either 0.9.0 works on Canton X and later, or consumers must wait for the network upgrade.
Canton 3.6.1 rejects the top-level filter and verbose fields of an
active-contracts request with DEPRECATED_API_DISABLED. The example
now sends both inside eventFormat, as canton-lib v0.11.0 does.
The party key now closes the single quotes, so the shell expands
$SENDER_PARTY_ID. Before, the request sent the literal variable name.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The entry said that every active-contracts query returned an empty
result on Canton 3.6.1. Only the websocket queries did. Mint and
redeem call the HTTP get_by_party, which already returned an error,
and the new "Ledger API returned" text comes only from the websocket
functions.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A service owner on TestNet or MainNet must decide when to bump. The
entry now says that the release is tested on Canton 3.6.1 only, and
what the participant's error suggests about Canton 3.4.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@hubagaspar91 thanks for the review. I checked all three findings against the code, and all three are correct.
OPS-03 · README curl example. Fixed in 80c3a7d. The "Get Active Contracts" example now sends filtersByParty and verbose inside eventFormat, the same shape that canton-lib v0.11.0 sends. The example had a second fault: $SENDER_PARTY_ID was inside single quotes, so the shell did not expand it. The commit fixes that too. I expanded the body with test values and checked it with jq. I did not send it to a participant. I searched the repo for other active-contracts bodies with a top-level filter, and this was the only one.
COR-01 · Mint and redeem. Fixed in d296008. You are right. Mint and redeem call get_by_party over HTTP, and at the v0.9.0 tag it returns Err("post_v2_state_active_contracts failed: ..."). The CHANGELOG now separates the two paths. It also says that the Ledger API returned text comes only from the websocket functions. The wrong claim was in three places: the CHANGELOG and two lines of the PR body. I corrected all three. #95 tracks the redeem.rs doc comments.
OPS-01 · Supported Canton versions. Fixed in 2e6bbac. I have no TestNet credentials, so I could not run the query. The CHANGELOG now says that 0.9.0 is tested on Canton 3.6.1 only. It also says that the error suggests support from 3.4, and that nobody has tested an older participant. The PR caveats say the same.
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
The API client requirements are caret ranges rather than exact pins, allowing untested generated API variants in downstream builds.
0 open findings
Previously missed (2)
In code that hasn't changed since last review
Use an exact client version pin in both manifests
Cargo.toml:23
This is not an exact pin: Cargo interprets a bare version as a caret requirement, so consumers (whose resolution does not use this repository's lockfile) may select a later matching 3.6.1 prerelease or stable release. That is unsafe here because the generated Kind layout is version-sensitive and the release is explicitly validated only with 3.6.1-0.1.0. Use an exact requirement in both manifests so downstream builds retain the tested client API.
Pin the TUI client dependency to the tested exact version
cbtc-tui/Cargo.toml:8
This bare version remains a caret requirement rather than the promised pin. Without the workspace lockfile, the TUI can resolve a later compatible-looking client release whose generated Kind variants differ, invalidating the KindOneOf4 match. Keep this manifest exact as well.
🧠 Review effort: Balanced
Give feedback about Copilot approvals in this survey to enter a drawing for a $150 gift card.
Round 3 reported 2 findings that it marks as previously missed. Both ask for an exact canton-api-client = "=3.6.1-0.1.0" pin, in Cargo.toml:23 and cbtc-tui/Cargo.toml:8.
Won't fix. The requirement stays "3.6.1-0.1.0":
A library normally declares a caret range, and the lockfile fixes the exact version. An exact pin in a library can block a consumer's dependency resolution.
canton-lib v0.11.0 declares the same requirement in the same form. The old "3.6.0-0.1.0" requirement was in this form too, and this repo has no exact pins.
cbtc-tui is a workspace member, so it builds with the committed Cargo.lock, which holds 3.6.1-0.1.0.
Only cbtc-tui matches on Kind, and the library does not. If a later client changes the generated variants, the build fails to compile. It does not misbehave silently, because each variant has a different field name.
Copilot is correct that the range also allows a later regeneration, such as 3.6.1-0.2.0. The pilot decided to keep the range for the reasons above.
Outcome: converged. Open items: none. Huba's review findings are answered separately, in this comment.
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
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.
What this PR does
Old behavior
cbtc-lib pins canton-lib v0.9.0. That version sends the
filterandverbosefields in every active-contracts request. Canton 3.6.1 rejects both fields withDEPRECATED_API_DISABLED.The effect of that rejection depends on the path the query takes:
cbtc::active_contracts::getand thecbtc-tuibalance query. canton-lib v0.9.0 reads the error message as a stream with no contracts and returns an empty result. Nothing logs an error. On devnet, a balance check reported 0 for a party that holds 4 holdings.ledger::active_contracts::get_by_party, and it returns an error. So mint and redeem fail withpost_v2_state_active_contracts failed: ....The Security workflow also fails on every PR and on
main.New behavior
cbtc-lib pins canton-lib v0.11.0, the latest release. That release includes these changes:
eventFormatinstead of the disabled fields, so the participant accepts the queries again.Err("Ledger API returned <code>: <cause>")instead of returning an empty result. The HTTP path keeps itspost_v2_state_active_contracts failedtext.canton-api-clientto 3.6.1, which is generated from the Canton 3.6.1 OpenAPI spec.Cargo Deny passes. The Cargo Audit job is removed.
Verification
I ran the
check_balanceexample on devnet. All devnet participants run Splice 0.9.0, which ships Canton 3.6.1. Both builds queried the same party with the same credentials:main(be95c7f)763bcc3)cargo clippy --workspace --all-targets -- -D warningspasses on the pinned rustc 1.94.1.cargo test --workspace --all-targetspasses on rustc 1.94.1: 98 passed, 0 failed, 6 ignored.parses_and_aggregates_party_rightspasses. It checks thatcbtc-tuireads the act and read rights from the new client'sKindvariants.I ran the
cbtc-tuilogin code on devnet with a temporary test, which I did not commit. The test imports the profile from a.envfile, logs in to Keycloak and callsfetch_parties. Both builds used the same user:main(be95c7f)763bcc3)The 4 rights are 2 act-as rights and 2 read-as rights. If the PR matched the wrong
Kindvariant, both parties would showread=false.Cargo.lockholds one entry each forcommon,ledger,token,keycloak,registryandcanton-api-client. The canton-lib crates are atv0.11.0(87646b7), and the client is at 3.6.1-0.1.0. So no second copy of canton-lib or of the client is built.Cargo Deny passes in CI on
2e6bbac. Both Socket Security checks pass too.I did not run the 6 ignored live tests. The devnet runs check read-only calls. They do not check mint, redeem, a transfer or the
cbtc-tuiscreens.The change that enables it
Cargo.tomland the two incbtc-tui/Cargo.tomlmove fromv0.9.0tov0.11.0.canton-api-clientmoves from 3.6.0-0.1.0 to 3.6.1-0.1.0 in both manifests.parse_party_rightsincbtc-tui/src/session.rsmatchesKind::KindOneOf4forCanReadAs, notKindOneOf3. This is the only Rust change.eventFormatinstead of the disabled top-level fields. It also expands$SENDER_PARTY_ID, which it sent as literal text before.h2goes from 0.4.12 to 0.4.19 inCargo.lock.cargo-auditjob is removed from.github/workflows/security.yml.Caveats
canton-api-client. That consumer must move its canton-lib pin tov0.11.0and its client to 3.6.1-0.1.0 in the same change.Kindvariants by number must check them. Client 3.6.1 moves every variant afterKindOneOfup by one.eventFormatworks from 3.4. Nobody has tested a TestNet or MainNet participant yet, and the CHANGELOG says so.src/mint_redeem/redeem.rssay thatlist_holdingsopens a websocket, but it uses HTTP. Those comments are older than this PR, so Correct the list_holdings doc comments in redeem.rs #95 tracks them.v0.9.0. The DevNet participants already run 3.6.1, so a DevNet service that has not been bumped now reads empty balances, and its mint and redeem calls fail. The later upgrades are TestNet on 2026-10-28 and MainNet on 2026-11-07.Details
Why v0.11.0 and not v0.10.1
canton-lib released v0.11.0 on 2026-10-08, before this PR merged. If cbtc-lib released on v0.10.1, every service would need a second breaking bump soon after. Each canton-lib tag is a separate Cargo source, so a service cannot mix cbtc 0.9.0 on v0.10.1 with its own pin on v0.11.0.
Why the client pin moves
ledgerre-exportscanton_api_client::models, and cbtc uses both paths. For example,src/mint_redeem/models.rsimportsJsActiveContractfrom the client, andredeem.rsimports it fromledger::models. Two client versions make these two different types, and the build fails. The old requirement3.6.0-0.1.0is a pre-release version, so Cargo does not match it to 3.6.1-0.1.0.Why the
Kindvariant changesClient 3.6.1 adds the
CanActAsAnyPartyuser right. The OpenAPI generator numbers the variants ofKindin order:CanActAsKindOneOfKindOneOfCanActAsAnyPartyKindOneOf1CanReadAsKindOneOf3KindOneOf4In client 3.6.1,
KindOneOf3isCanExecuteAsAnyParty, so the old code does not compile.Why the Cargo Audit job goes
The job fails before it checks a single dependency:
rustsec/audit-check@v2.0.0action compilescargo-auditfrom source on every run.--locked, so Cargo picks the newest dependency versions.kstring2.0.5, needs rustc 1.96.0. This repo pins rustc 1.94.1.The Security run on
mainatbe95c7fshows the error: "rustc 1.94.1 is not supported by the following package: kstring@2.0.5 requires rustc 1.96.0".The advisory coverage stays the same. Cargo Deny reads the same RustSec database, and it installs a prebuilt binary, so the rustc pin does not affect it. canton-lib removed the same job for the same reason in DLC-link/canton-lib#61.
You can keep cargo-audit as a second check instead. There are two ways to do that, and each belongs in its own PR:
cargo-audit, or build it on a newer toolchain inside the job.Why 0.9.0 and not 0.8.1
cbtc's own API does not change. But cbtc re-exports
commontypes such asDamlDecimal, andcommonmoves from 0.9.0 to 0.11.0. cbtc's public functions also takeledger::modelstypes, such asfrom_active_contract. Under 0.x SemVer, these are breaking upgrades of public dependencies. A consumer that pins canton-lib v0.9.0 next to cbtc 0.9.0 gets twocommonpackages, and its code stops compiling.Why both manifests move
cbtc-tuipins canton-lib separately. If only the root manifest moves, the TUI keeps canton-lib v0.9.0 and reads empty results on 3.6.1.Security
h20.4.12 carries RUSTSEC-2026-0258, which made Cargo Deny fail. 0.4.19 is the version that canton-lib v0.11.0 locks. This lockfile sets the version forcbtc-tuiand the examples only. A consumer's own lockfile sets it for that consumer.Commits
Commits 7 to 9 address the review by @hubagaspar91.
The branch name still says
0.10.0, but the PR pinsv0.11.0.After merge
Tag the merge commit
v0.9.0and publish the release. The CHANGELOG dates the release 2026-10-08. If the merge happens on another day, change that date first.Depends on DLC-link/canton-lib#61 (v0.10.0), DLC-link/canton-lib#62 (v0.10.1) and DLC-link/canton-lib#63 (v0.11.0).
🤖 Generated with Claude Code