Add Token Registry utilities + Integration tests - #668
Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces a new registry-kit Go module providing Canton Registry utility onboarding/mint/supply verification helpers plus CCIP “token registry” utilities, and wires these utilities into existing CCIP integration tests.
Changes:
- Added
registry-kitCLI + config/state management for devnet Registry onboarding, minting, and CCIP TokenAdminRegistry linking. - Added registry/CCIP utility helpers (ACS discovery, choice-context building, disclosures, pool deploy/send/release helpers, package/DAR checks).
- Updated integration tests to consume
registry-kitand added generated bindings / contract package metadata for Utility DARs.
Reviewed changes
Copilot reviewed 40 out of 58 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| registry-kit/registry/verify.go | Adds holding verification utilities (template + interface view + aggregated balance). |
| registry-kit/registry/supply.go | Adds supply aggregation query over Registry Holding contracts. |
| registry-kit/registry/packages.go | Adds Utility DAR loading and package presence checks. |
| registry-kit/registry/onboarding.go | Adds devnet onboarding flows for Provider/Registrar services + instrument configuration creation. |
| registry-kit/registry/mint.go | Adds local mint flow via AllocationFactory with manually assembled choice-context. |
| registry-kit/registry/mint_devnet.go | Adds devnet mint flow using DA operator backend choice-context + disclosures. |
| registry-kit/registry/discover.go | Adds ACS discovery for Registry service/factory contracts. |
| registry-kit/registry/context.go | Adds Registry mint choice-context construction helpers. |
| registry-kit/registry/bootstrap.go | Adds local bootstrap for Registry services (operator=provider=registrar). |
| registry-kit/registry/acs.go | Adds generic ACS contract lookup helpers by template/entity. |
| registry-kit/registry-kit.yaml.example | Adds example devnet configuration (TOML-formatted). |
| registry-kit/operator/backend.go | Adds HTTP client for DA operator backend choice-context + disclosed contract parsing. |
| registry-kit/main.go | Adds CLI entrypoint for canton-registry-kit. |
| registry-kit/ledger/parse.go | Adds transaction parsing helpers (created contract IDs, lock/burn & release outputs). |
| registry-kit/ledger/devnet_client.go | Adds devnet client connection helper using CLDF RPC participant + auth. |
| registry-kit/ledger/ctf_client.go | Adds participant-backed command submission wrapper (create/exercise + disclosures). |
| registry-kit/ledger/client.go | Adds ledger client interface abstraction for registry-kit. |
| registry-kit/go.mod | Introduces standalone Go module for registry-kit. |
| registry-kit/config/state.go | Adds persisted state file for CLI progress tracking. |
| registry-kit/config/config.go | Adds config loader/validator and party-role selection helpers. |
| registry-kit/config/config_test.go | Adds config + state round-trip test. |
| registry-kit/cmd/runtime.go | Adds CLI runtime (config/state loading, connecting, operator client, timeouts). |
| registry-kit/cmd/root.go | Adds Cobra root command + global flags. |
| registry-kit/cmd/operator.go | Adds CLI commands for TAR linking and validation. |
| registry-kit/cmd/onboarding.go | Adds CLI onboarding commands (package checks, provider service request/wait, registrar onboarding, discovery). |
| registry-kit/cmd/issuer.go | Adds CLI issuer lifecycle commands (create instrument, mint, accept mint, query supply). |
| registry-kit/ccip/validate.go | Adds read-only TAR/pool mapping validation and holdings visibility checks. |
| registry-kit/ccip/send.go | Adds BurnMintTokenPool LockOrBurn helpers + SendingMessage creation and TAR factory config. |
| registry-kit/ccip/release.go | Adds BurnMintTokenPool ReleaseFromTicket helper. |
| registry-kit/ccip/register.go | Adds TAR token pool registration helpers (sequence-based + explicit actAs via ledger client). |
| registry-kit/ccip/pool_context.go | Adds disclosure builders and nested extraContext construction for pool send/release/execute. |
| registry-kit/ccip/pool_context_v1.go | Adds “latest bindings” variant of pool extraContext for integration-test compatibility. |
| registry-kit/ccip/deploy.go | Adds helpers to deploy rate limiters and burn/mint pools for a given owner party. |
| registry-kit/ccip/bundle.go | Adds CLDF operations bundle helper. |
| integration-tests/go.mod | Adds local replace for registry-kit and switches canton dep to local v0.0.0. |
| integration-tests/ccip/registry_send_helpers_test.go | Adds helpers for building pool disclosures/choice-context for registry token pool tests. |
| integration-tests/ccip/ccip_execute_token_registry_test.go | Adds full receive-flow integration test using Registry holdings + registrar-owned token pool. |
| contracts/contracts.go | Adds Utility DAR packages + pinned package IDs + splice package constants. |
| contracts/cmd/bindings/main.go | Adjusts bindings generation to skip prim/stdlib dalfs. |
| bindings/generated/latest/utility/registry_holding_v0/tuple2.go | Adds Tuple2 shim type required by utility DAR bindings. |
| bindings/generated/latest/utility/credential_v0/tuple2.go | Adds Tuple2 shim type required by utility DAR bindings. |
| bindings/generated/latest/utility/credential_v0/credential_v0.go | Adds generated utility credential bindings. |
| bindings/generated/latest/splice/splice_api_token_allocation_v1/splice_api_token_allocation_v1.go | Adds generated splice allocation bindings. |
| bindings/generated/latest/splice/splice_api_token_allocation_instruction_v1/splice_api_token_allocation_instruction_v1.go | Adds generated splice allocation-instruction bindings. |
| bindings/generated/latest/splice/splice_api_featured_app_v1/splice_api_featured_app_v1.go | Adds generated splice featured-app bindings. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
9969f76 to
2a2b453
Compare
add integration tests with registry fix rebase add small fixes fix lint tidy mods remove not used reg dars add registry mod to ci remove utility dars
2a2b453 to
e229d2f
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 54 out of 66 changed files in this pull request and generated 1 comment.
Files not reviewed (1)
- contracts/cmd/bindings/utility_patch.go: Generated file
Suppressed comments (8)
registry-kit/registry/acs.go:51
- FindFirstContractByEntity also accepts template as
any; with FindContractsByEntity updated to require GetTemplateID, this helper should use the same interface type to avoid runtime panics and keep the API consistent.
registry-kit/registry/supply.go:39 - QuerySupply filters holdings only by Instrument.Id and ignores the instrument admin/registrar. If two registrars use the same instrument ID string, this will aggregate unrelated holdings into the same supply total.
registry-kit/registry/mint_devnet.go:121 - FindMintRequestForInstrument takes an instrumentID parameter but never uses it, so it can return a MintRequest for a different instrument when multiple requests exist in the ACS.
registry-kit/registry/packages.go:83 - PackageCheckResult.FoundID is always set to the expected ID even when the package is missing, which makes the result struct misleading for callers/logging.
registry-kit/registry/acs.go:21 - FindContractsByEntity uses a forced type assertion (template.(interface{ GetTemplateID() string })) which will panic at runtime if a caller passes the wrong template type. Since GetTemplateID is the only requirement, accept an interface type in the signature instead.
This issue also appears on line 48 of the same file.
registry-kit/ccip/pool_context.go:217
- DisclosePoolReleaseContracts always uses the provided
clientfor disclosing CCIP-owned contracts (TokenAdminRegistry, RMNRemote, TokenReceiveTicket). This makes the helper unusable in the same multi-participant setups that PoolSend/PoolExecute support via a separate CcipClient.
integration-tests/ccip/ccip_execute_test.go:87 - finalityConfigValueFromBlockConfirmations no longer accepts a blockConfirmations argument, but the name still implies it does. Making the parameter optional (variadic) keeps the current call sites working while restoring the meaning of the name (and the previous WaitForFinality behavior for 0).
func finalityConfigValueFromBlockConfirmations() *apiv2.Value {
return &apiv2.Value{Sum: &apiv2.Value_Variant{Variant: &apiv2.Variant{
Constructor: "BlockDepth",
Value: &apiv2.Value{Sum: &apiv2.Value_Int64{Int64: 2000}},
}}}
}
contracts/utilitydars/fetch.go:188
- downloadBundle uses http.DefaultClient with no timeout. If ctx has no deadline/cancel, a network stall can hang indefinitely while fetching the utility DAR bundle (and GetDar currently calls EnsureCache with context.Background()). Consider using an http.Client with a sane Timeout and/or enforcing a default deadline when ctx has none.
func downloadBundle(ctx context.Context, url string) ([]byte, error) {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
if err != nil {
return nil, fmt.Errorf("create utility bundle request: %w", err)
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, fmt.Errorf("download utility bundle: %w", err)
}
defer resp.Body.Close()
| // EncodeUint256Hex encodes a base-10 integer string as a 32-byte hex string (CCIP MessageCodec style). | ||
| func EncodeUint256Hex(decimalValue string) string { | ||
| n := new(big.Int) | ||
| _, ok := n.SetString(decimalValue, 10) | ||
| if !ok { | ||
| panic("invalid decimal: " + decimalValue) | ||
| } | ||
| hexStr := n.Text(16) | ||
| return strings.Repeat("0", 64-len(hexStr)) + hexStr | ||
| } |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 55 out of 68 changed files in this pull request and generated 1 comment.
Files not reviewed (1)
- contracts/cmd/bindings/utility_patch.go: Generated file
Suppressed comments (4)
registry-kit/ccip/send.go:271
EncodeUint256Hexcurrently panics on parse failures and can also panic if the input overflows 256 bits (negative padding length). Since this is in a non-test package and exported, it should return an error instead of panicking and validate uint256 bounds.
contracts/utilitydars/fetch.go:186downloadBundleuseshttp.DefaultClientwith no timeout. Since this can run in CI or at runtime (viacontracts.GetDar), a stalled connection can hang indefinitely. Use anhttp.Clientwith a reasonable timeout (or enforce a context deadline).
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, fmt.Errorf("download utility bundle: %w", err)
}
registry-kit/registry/packages.go:83
CheckPackagessetsFoundIDtoexpectedIDeven when the package is missing, which makes the per-package results misleading (a missing package appears to have a found ID). Consider using the actual found ID from the lookup (empty when missing).
integration-tests/ccip/ccip_execute_test.go:86finalityConfigValueFromBlockConfirmationsno longer accepts a block depth and always returns a constant (2000), so the name is now misleading and may confuse future changes/tests. Consider renaming it to reflect the fixed value or reintroducing the parameter.
func finalityConfigValueFromBlockConfirmations() *apiv2.Value {
return &apiv2.Value{Sum: &apiv2.Value_Variant{Variant: &apiv2.Variant{
Constructor: "BlockDepth",
Value: &apiv2.Value{Sum: &apiv2.Value_Int64{Int64: 2000}},
}}}
| for i := range len(raw) { | ||
| if raw[i] == ':' { | ||
| out = append(out, raw[start:i]) | ||
| start = i + 1 | ||
| } | ||
| } |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 55 out of 68 changed files in this pull request and generated 1 comment.
Files not reviewed (1)
- contracts/cmd/bindings/utility_patch.go: Generated file
Suppressed comments (1)
registry-kit/registry/packages.go:83
FoundIDis always set to the expected package ID, even when the package is missing. This makes the output misleading (a missing package will still report a non-empty FoundID). Set FoundID only whenfoundis true (or populate it from the installed package details).
| func FindContractsByEntity(ctx context.Context, client ledger.Client, party string, template any, entityName string) ([]ContractRef, error) { | ||
| tplID := contracts.IdentifierFromBinding(template.(interface{ GetTemplateID() string })) | ||
| active, err := testhelpers.ListActiveContractsByTemplateId(ctx, client.ForParty(party), tplID) |
Uh oh!
There was an error while loading. Please reload this page.