Context
Canton's Interactive Submission API enables a 2-step transaction flow: prepare a transaction (get a hash), sign the hash externally, then execute with the signature. This is the foundation for both external parties (#109) and non-custodial signing (#111).
This issue implements the infrastructure only -- it can be developed and tested against internal parties first to validate compatibility with Canton 3.4.8 before committing to the external party migration.
Note: The codebase has been restructured. pkg/canton/ is now pkg/cantonsdk/ with a modular architecture: ledger/ (gRPC client), token/ (CIP-56 ops), identity/ (party management), bridge/ (bridge ops).
Tasks
Proto Generation
Ledger Client Integration
Signature Encoding
Prepare/Execute Helper
Validation
Files Affected
| File |
Change |
scripts/setup/generate-protos.sh |
Add interactive proto generation |
pkg/cantonsdk/lapi/v2/interactive/*.pb.go |
NEW - generated stubs |
pkg/cantonsdk/ledger/client.go |
Add Interactive() to Ledger interface + Client impl |
pkg/cantonsdk/token/client.go |
Add prepareAndExecuteAsUser(), wire into transferHolding() |
pkg/keys/canton_keys.go |
Add SignDER() method |
Notes
- Interactive Submission is marked "Alpha 3.3" in proto comments, expected stable in 3.5. This issue validates compatibility before we depend on it for external parties.
PrepareSubmission only requires readAs scope (not actAs) per the proto -- the signature provides authorization.
- The current
transferHolding() in pkg/cantonsdk/token/client.go:405 uses ActAs: [fromPartyID] via standard CommandService.SubmitAndWait -- this is the method that needs the InteractiveSubmission path.
Related Issues
Context
Canton's Interactive Submission API enables a 2-step transaction flow: prepare a transaction (get a hash), sign the hash externally, then execute with the signature. This is the foundation for both external parties (#109) and non-custodial signing (#111).
This issue implements the infrastructure only -- it can be developed and tested against internal parties first to validate compatibility with Canton 3.4.8 before committing to the external party migration.
Note: The codebase has been restructured.
pkg/canton/is nowpkg/cantonsdk/with a modular architecture:ledger/(gRPC client),token/(CIP-56 ops),identity/(party management),bridge/(bridge ops).Tasks
Proto Generation
go_packageoptions into the 3 interactive proto files:proto/.../interactive/interactive_submission_service.protoproto/.../interactive/interactive_submission_common_data.protoproto/.../interactive/transaction/v1/interactive_submission_data.protoscripts/setup/generate-protos.shto include interactive proto directorypkg/cantonsdk/lapi/v2/interactive/Ledger Client Integration
Interactive()method to theLedgerinterface inpkg/cantonsdk/ledger/client.goreturninginteractive.InteractiveSubmissionServiceClientledger.New()from the existinggrpc.ClientConnSignature Encoding
pkg/keys/canton_keys.go-- currentSign()returns raw R||S (64 bytes) despite the comment saying "DER format". Add aSignDER()method producing ASN.1 DER-encoded ECDSA signatures as Canton expects.Prepare/Execute Helper
prepareAndExecuteAsUser()helper inpkg/cantonsdk/token/client.gothat:PrepareSubmissionvia the ledger'sInteractive()clientprepared_transaction_hashwith a provided private key (secp256k1 ECDSA-SHA256, DER format)PartySignatureswith the party ID and DER signatureExecuteSubmissionAndWaitwith the prepared transaction + signaturestransferHolding()(line 405) as an alternative submission path when a signing key is providedValidation
PrepareSubmission+ExecuteSubmissionround-trip against Canton 3.4.8SIGNING_ALGORITHM_SPEC_EC_DSA_SHA_256)Files Affected
scripts/setup/generate-protos.shpkg/cantonsdk/lapi/v2/interactive/*.pb.gopkg/cantonsdk/ledger/client.goInteractive()toLedgerinterface +Clientimplpkg/cantonsdk/token/client.goprepareAndExecuteAsUser(), wire intotransferHolding()pkg/keys/canton_keys.goSignDER()methodNotes
PrepareSubmissiononly requiresreadAsscope (notactAs) per the proto -- the signature provides authorization.transferHolding()inpkg/cantonsdk/token/client.go:405usesActAs: [fromPartyID]via standardCommandService.SubmitAndWait-- this is the method that needs the InteractiveSubmission path.Related Issues