Skip to content

scripts: devnet testing scripts for USDCx and Splice token-standard#256

Open
salindne wants to merge 1 commit into
mainfrom
feat/devnet-testing-scripts
Open

scripts: devnet testing scripts for USDCx and Splice token-standard#256
salindne wants to merge 1 commit into
mainfrom
feat/devnet-testing-scripts

Conversation

@salindne
Copy link
Copy Markdown
Contributor

@salindne salindne commented May 6, 2026

Summary

Adds 10 standalone Go scripts (//go:build ignore) under scripts/testing/ for probing Canton devnet behavior outside the main API-server code paths, plus a TLS/ALPN fix to scripts/remote/grant-any-party-rights.go so it works against TLS-enabled devnet endpoints (not just local).

The headline script is accept-via-interface.go — a full reference implementation of the USDCx receive path: registrar HTTP choice-context call, AnyValue ADT encoder, DisclosedContracts builder, and TransferInstruction_Accept exercise via Interactive Submission. Validated end-to-end against chainsafe devnet 2026-05-06 (10 USDCx received from a Loop wallet).

This is a tools-only PR — no library or API server changes. The scripts are self-contained, gated by //go:build ignore so they don't affect go build ./... or test runs.

What each script does

Script Purpose
allocate-standalone-party.go AllocateExternalParty + write keys to a credentials file; bypasses the middleware DB
check-party-hosted.go Verify a party is IsLocal on our participant via PartyManagementService.GetParties
check-holdings.go Query Splice HoldingV1 interface holdings for a given party
list-all-contracts.go Wildcard ACS query, prints every contract visible to a party with template + arg summary
list-packages.go Call PackageService.ListPackages
find-transfer-rule.go Wildcard query for TransferRule contracts via filters_for_any_party
inspect-package.go Printable-string extractor over a Canton package archive (useful for discovering choice/module names without LF parsing)
accept-usdcx-transfer.go Direct TransferOffer_Accept template exercise (negative-result reference — confirms the choice is not on the concrete template)
accept-via-interface.go Reference implementation of the full USDCx receive path. Validated on devnet.
create-holder-service-request.go Create a HolderServiceRequest (kept as reference for the xReserve bridge flow; not needed for basic USDCx transfers)

TLS/ALPN fix

scripts/remote/grant-any-party-rights.go now dials with NewTLSWithALPNDisabled when TLS is enabled in config, falling back to insecure when not — mirroring the SDK ledger client. Without this, the script can't reach devnet's TLS-fronted gRPC endpoint.

Why this matters

accept-via-interface.go is the executable spec for the USDCx receive flow that the middleware needs to support (custodial auto-accept worker + non-custodial dApp-driven accept). It demonstrates:

  • The registrar's per-instruction choice-context endpoint shape (POST {host}/api/token-standard/v0/registrars/{registrar}/registry/transfer-instruction/v1/{cid}/choice-contexts/accept)
  • That choiceContext is Map Text AnyValue (not Map Text Text as PR Integrate Transfer Factory Registry API for USDCx transfers #214 assumed) — full AV_* tag encoder included
  • That disclosedContracts templateId arrives in string form (<pkgHex>:<Module.Path>:<Entity>) and synchronizerId is empty (fall back to cfg.Canton.DomainID)
  • That no HolderService onboarding or operator interaction is required for basic USDCx transfers — only the public registrar HTTP API + Splice CIP-56 interface choices

Test plan

  • go build ./... still passes (scripts are gated by //go:build ignore)
  • go test ./... still passes (no library code touched)
  • make lint clean
  • Smoke test on devnet: go run scripts/testing/list-packages.go -config config.api-server.devnet-test.yaml returns >0 packages
  • (manual, requires party credentials) go run scripts/testing/accept-via-interface.go -dry-run prints a registrar response and disclosed-contract count without submitting

Adds 10 standalone Go scripts (build tag `ignore`) for probing Canton
devnet behavior outside the main API-server flow, and a TLS/ALPN fix
to grant-any-party-rights.go so it works against TLS-enabled devnet
endpoints (not just local).

Scripts are self-contained: each takes flags for config and (where
needed) a credentials file, and runs through the existing cantonsdk
client. Useful for exercising new ledger features and validating
end-to-end USDCx flows before porting into the middleware proper.

scripts/testing/:
- allocate-standalone-party.go — AllocateExternalParty + write keys
  to a credentials file; bypasses the middleware DB.
- check-party-hosted.go — verify a party is IsLocal on our
  participant via PartyManagementService.GetParties.
- check-holdings.go — query Splice HoldingV1 interface holdings for
  a given party.
- list-all-contracts.go — wildcard ACS query, prints every contract
  visible to a party with a template + arg summary.
- list-packages.go — call PackageService.ListPackages.
- find-transfer-rule.go — wildcard query for TransferRule contracts
  via filters_for_any_party.
- inspect-package.go — printable-string extractor over a Canton
  package archive (useful for discovering choice/module names
  without LF parsing).
- accept-usdcx-transfer.go — direct TransferOffer_Accept template
  exercise (negative-result reference: confirms the choice is not
  on the concrete template).
- accept-via-interface.go — full reference implementation of the
  USDCx receive path: registrar choice-context HTTP call, AnyValue
  encoder, DisclosedContracts builder, TransferInstruction_Accept
  exercise via Interactive Submission. Validated end-to-end on
  chainsafe devnet.
- create-holder-service-request.go — create a HolderServiceRequest
  (kept as reference for the xReserve bridge flow; not needed for
  basic USDCx transfers).

scripts/remote/grant-any-party-rights.go: dial with
NewTLSWithALPNDisabled when TLS is enabled in config, falling back
to insecure when not. Mirrors the SDK ledger client.
@codecov-commenter
Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (main@cfefed3). Learn more about missing BASE report.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main     #256   +/-   ##
=======================================
  Coverage        ?   32.33%           
=======================================
  Files           ?      127           
  Lines           ?     8968           
  Branches        ?        0           
=======================================
  Hits            ?     2900           
  Misses          ?     5818           
  Partials        ?      250           
Flag Coverage Δ
unittests 32.33% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a suite of testing and utility scripts for the Canton middleware, covering party allocation, contract discovery, and USDCx transfer acceptance. It also updates existing scripts to support TLS for gRPC connections. The review feedback correctly identifies multiple instances where the import paths for the Canton V2 API violate the repository style guide; specifically, Rule 1 requires using pkg/canton/lapi/v2 (and its subpackages) instead of pkg/cantonsdk/lapi/v2.

"time"

canton "github.com/chainsafe/canton-middleware/pkg/cantonsdk/client"
lapiv2 "github.com/chainsafe/canton-middleware/pkg/cantonsdk/lapi/v2"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The import path github.com/chainsafe/canton-middleware/pkg/cantonsdk/lapi/v2 violates the Repository Style Guide (Rule 1). Please use github.com/chainsafe/canton-middleware/pkg/canton/lapi/v2 with alias lapiv2.

Suggested change
lapiv2 "github.com/chainsafe/canton-middleware/pkg/cantonsdk/lapi/v2"
lapiv2 "github.com/chainsafe/canton-middleware/pkg/canton/lapi/v2"
References
  1. ALWAYS import github.com/chainsafe/canton-middleware/pkg/canton/lapi/v2 with alias lapiv2. (link)

"time"

canton "github.com/chainsafe/canton-middleware/pkg/cantonsdk/client"
lapiv2 "github.com/chainsafe/canton-middleware/pkg/cantonsdk/lapi/v2"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The import path github.com/chainsafe/canton-middleware/pkg/cantonsdk/lapi/v2 violates the Repository Style Guide (Rule 1). Please use github.com/chainsafe/canton-middleware/pkg/canton/lapi/v2 with alias lapiv2.

Suggested change
lapiv2 "github.com/chainsafe/canton-middleware/pkg/cantonsdk/lapi/v2"
lapiv2 "github.com/chainsafe/canton-middleware/pkg/canton/lapi/v2"
References
  1. ALWAYS import github.com/chainsafe/canton-middleware/pkg/canton/lapi/v2 with alias lapiv2. (link)

"time"

canton "github.com/chainsafe/canton-middleware/pkg/cantonsdk/client"
lapiv2 "github.com/chainsafe/canton-middleware/pkg/cantonsdk/lapi/v2"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The import path github.com/chainsafe/canton-middleware/pkg/cantonsdk/lapi/v2 violates the Repository Style Guide (Rule 1). Please use github.com/chainsafe/canton-middleware/pkg/canton/lapi/v2 with alias lapiv2.

Suggested change
lapiv2 "github.com/chainsafe/canton-middleware/pkg/cantonsdk/lapi/v2"
lapiv2 "github.com/chainsafe/canton-middleware/pkg/canton/lapi/v2"
References
  1. ALWAYS import github.com/chainsafe/canton-middleware/pkg/canton/lapi/v2 with alias lapiv2. (link)

"time"

cfgpkg "github.com/chainsafe/canton-middleware/pkg/config"
lapiv2 "github.com/chainsafe/canton-middleware/pkg/cantonsdk/lapi/v2"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The import path github.com/chainsafe/canton-middleware/pkg/cantonsdk/lapi/v2 violates the Repository Style Guide (Rule 1). Please use github.com/chainsafe/canton-middleware/pkg/canton/lapi/v2 with alias lapiv2.

Suggested change
lapiv2 "github.com/chainsafe/canton-middleware/pkg/cantonsdk/lapi/v2"
lapiv2 "github.com/chainsafe/canton-middleware/pkg/canton/lapi/v2"
References
  1. ALWAYS import github.com/chainsafe/canton-middleware/pkg/canton/lapi/v2 with alias lapiv2. (link)

"time"

cfgpkg "github.com/chainsafe/canton-middleware/pkg/config"
lapiv2 "github.com/chainsafe/canton-middleware/pkg/cantonsdk/lapi/v2"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The import path github.com/chainsafe/canton-middleware/pkg/cantonsdk/lapi/v2 violates the Repository Style Guide (Rule 1). Please use github.com/chainsafe/canton-middleware/pkg/canton/lapi/v2 with alias lapiv2.

Suggested change
lapiv2 "github.com/chainsafe/canton-middleware/pkg/cantonsdk/lapi/v2"
lapiv2 "github.com/chainsafe/canton-middleware/pkg/canton/lapi/v2"
References
  1. ALWAYS import github.com/chainsafe/canton-middleware/pkg/canton/lapi/v2 with alias lapiv2. (link)

"time"

cfgpkg "github.com/chainsafe/canton-middleware/pkg/config"
lapiv2 "github.com/chainsafe/canton-middleware/pkg/cantonsdk/lapi/v2"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The import path github.com/chainsafe/canton-middleware/pkg/cantonsdk/lapi/v2 violates the Repository Style Guide (Rule 1). Please use github.com/chainsafe/canton-middleware/pkg/canton/lapi/v2 with alias lapiv2.

Suggested change
lapiv2 "github.com/chainsafe/canton-middleware/pkg/cantonsdk/lapi/v2"
lapiv2 "github.com/chainsafe/canton-middleware/pkg/canton/lapi/v2"
References
  1. ALWAYS import github.com/chainsafe/canton-middleware/pkg/canton/lapi/v2 with alias lapiv2. (link)

"time"

cfgpkg "github.com/chainsafe/canton-middleware/pkg/config"
lapiv2 "github.com/chainsafe/canton-middleware/pkg/cantonsdk/lapi/v2"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The import path github.com/chainsafe/canton-middleware/pkg/cantonsdk/lapi/v2 violates the Repository Style Guide (Rule 1). Please use github.com/chainsafe/canton-middleware/pkg/canton/lapi/v2 with alias lapiv2.

Suggested change
lapiv2 "github.com/chainsafe/canton-middleware/pkg/cantonsdk/lapi/v2"
lapiv2 "github.com/chainsafe/canton-middleware/pkg/canton/lapi/v2"
References
  1. ALWAYS import github.com/chainsafe/canton-middleware/pkg/canton/lapi/v2 with alias lapiv2. (link)

@@ -33,6 +33,9 @@ import (
adminv2 "github.com/chainsafe/canton-middleware/pkg/cantonsdk/lapi/v2/admin"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The import path github.com/chainsafe/canton-middleware/pkg/cantonsdk/lapi/v2/admin violates the Repository Style Guide (Rule 1). Please use github.com/chainsafe/canton-middleware/pkg/canton/lapi/v2/admin.

Suggested change
adminv2 "github.com/chainsafe/canton-middleware/pkg/cantonsdk/lapi/v2/admin"
adminv2 "github.com/chainsafe/canton-middleware/pkg/canton/lapi/v2/admin"
References
  1. ALWAYS import github.com/chainsafe/canton-middleware/pkg/canton/lapi/v2 with alias lapiv2. (link)

"time"

cfgpkg "github.com/chainsafe/canton-middleware/pkg/config"
adminv2 "github.com/chainsafe/canton-middleware/pkg/cantonsdk/lapi/v2/admin"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The import path github.com/chainsafe/canton-middleware/pkg/cantonsdk/lapi/v2/admin violates the Repository Style Guide (Rule 1). Please use github.com/chainsafe/canton-middleware/pkg/canton/lapi/v2/admin.

Suggested change
adminv2 "github.com/chainsafe/canton-middleware/pkg/cantonsdk/lapi/v2/admin"
adminv2 "github.com/chainsafe/canton-middleware/pkg/canton/lapi/v2/admin"
References
  1. ALWAYS import github.com/chainsafe/canton-middleware/pkg/canton/lapi/v2 with alias lapiv2. (link)

Copy link
Copy Markdown
Member

@dhyaniarun1993 dhyaniarun1993 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to merge this in main?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants