feat: add instrument_id to token config and splice_holding_package_id#227
feat: add instrument_id to token config and splice_holding_package_id#227
Conversation
Add InstrumentID and InstrumentAdmin fields to ERC20Token struct for per-token Canton instrument mapping. InstrumentID is required; InstrumentAdmin defaults to IssuerParty when empty. Add SpliceHoldingPackageID to cantonsdk/token.Config for Splice HoldingV1 interface queries (needed by #218 unified balance query). Update all config YAML files (defaults, test fixtures, e2e-local, devnet) with instrument_id per token and splice_holding_package_id. Closes #212
Codecov Report❌ Patch coverage is ❌ Your patch status has failed because the patch coverage (0.00%) is below the target coverage (50.00%). You can increase the patch coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## main #227 +/- ##
=======================================
Coverage ? 32.20%
=======================================
Files ? 126
Lines ? 8791
Branches ? 0
=======================================
Hits ? 2831
Misses ? 5710
Partials ? 250
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Code Review
This pull request introduces configuration for Canton instrument mapping and holding package IDs across various environment and test configuration files. Key changes include adding splice_holding_package_id to the Canton token configuration and instrument_id to the ERC-20 token metadata. Feedback highlights that the promised default logic for InstrumentAdmin is missing, and the new SpliceHoldingPackageID is currently unused in the client implementation. Additionally, the mainnet configuration files should use environment variables for the new package ID to maintain consistency with existing settings.
Address review feedback:
- Use ${CANTON_SPLICE_HOLDING_PACKAGE_ID} env var in mainnet configs
(consistent with other package ID fields)
- Add CANTON_SPLICE_HOLDING_PACKAGE_ID to setDefaultConfigEnv test helper
* feat: unified balance query via Splice HoldingV1 interface Add GetHoldingsByParty method that queries Canton using the Splice HoldingV1 interface as the user's own party, instead of querying CIP56Holding template as IssuerParty. This enables visibility of tokens issued by third parties (e.g., USDCx from Circle) where our IssuerParty is not a stakeholder on the holdings. GetHoldings now delegates to GetHoldingsByParty. GetAllHoldings retains the IssuerParty/template path for totalSupply and indexer use. Closes #218 * docs: clarify that CreateArguments is always populated for interface queries Canton Ledger API v2 proto marks create_arguments as Required on CreatedEvent, so decodeHolding works identically for both template-based and interface-based queries. Add comment to address review concern. * chore: add TODO for GetHoldingsByParty unit tests * feat: add USDCx to supported tokens config (#229) * feat: add USDCx to supported tokens config Add USDCx (USD Coin, 6 decimals) to supported_tokens in all config YAML files. This enables MetaMask to query balanceOf, symbol, decimals, and name for USDCx through the ERC-20 facade. USDCx is automatically added to the non-custodial transfer allowlist since it is derived from supported_tokens. Mainnet config uses ${CANTON_USDCX_INSTRUMENT_ADMIN} env var for the instrument admin (Circle's Bridge-Operator party). Closes #213 * feat: integrate Transfer Factory Registry API for external token transfers (#230) Add support for transferring tokens issued by external parties (e.g., USDCx from Circle) by routing factory discovery based on InstrumentAdmin: - Local tokens (InstrumentAdmin == IssuerParty): existing ACS query - External tokens: POST to Transfer Factory Registry API Key changes: - New RegistryClient (HTTP POST) calls Splice Transfer Factory Registry and parses factoryId, choiceContext, disclosedContracts from response - resolveTransferFactory routes by InstrumentAdmin automatically - DisclosedContracts from registry response threaded through PrepareSubmissionRequest for both custodial and non-custodial paths - EncodeExtraArgs now accepts choiceContext from registry response - ReadAs conditionally set: IssuerParty for local, empty for external - ExternalTokens config maps InstrumentAdmin → registry URL - WithRegistryClient option on token client constructor No breaking changes to public API (TransferByPartyID, PrepareTransfer). Routing is internal based on holdings data. Closes #214
The field was never read anywhere in the codebase. Transfer-factory routing uses InstrumentAdmin from the on-chain holding contract, not config. External tokens are handled via cantonsdk/token.Config.ExternalTokens keyed by admin party ID after #228. Removes the field, the instrument_admin yaml keys in local-devnet and mainnet configs, and the CANTON_USDCX_INSTRUMENT_ADMIN env var from config tests.
Resolve conflict in tests/e2e/tests/bridge/withdrawal_test.go: keep the *stack.Token pointer signature from this branch and the receiver.Address account from main (the test withdraws from receiver, not User1).
PR 228 made SpliceHoldingPackageID required on cantonsdk/token.Config. The e2e canton shim was missing it on both the DEMO and PROMPT token clients, causing every test to fail with 'splice_holding_package_id is required' at api/full stack init. Adds the constant alongside the other devnet package IDs (matches the value in config.api-server.local-devnet.yaml) and wires it into both token.Config instances.
Summary
InstrumentID(required) andInstrumentAdmin(optional, defaults to IssuerParty) fields toERC20Tokenconfig structSpliceHoldingPackageID(required) tocantonsdk/token.Configfor Splice HoldingV1 interface queriesinstrument_idper token andsplice_holding_package_idThis is the foundation for #218 (unified balance query) and #214 (transfer factory). Every token now specifies its Canton instrument ID, and the SDK config knows the Splice HoldingV1 package ID for interface-based ACS queries.
Closes #212
Test plan
go build ./...passes