Skip to content

Interactive Submission API infrastructure (prepare/sign/execute) #113

@salindne

Description

@salindne

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

  • Inject go_package options into the 3 interactive proto files:
    • proto/.../interactive/interactive_submission_service.proto
    • proto/.../interactive/interactive_submission_common_data.proto
    • proto/.../interactive/transaction/v1/interactive_submission_data.proto
  • Update scripts/setup/generate-protos.sh to include interactive proto directory
  • Generate Go stubs to pkg/cantonsdk/lapi/v2/interactive/

Ledger Client Integration

  • Add Interactive() method to the Ledger interface in pkg/cantonsdk/ledger/client.go returning interactive.InteractiveSubmissionServiceClient
  • Initialize the InteractiveSubmission gRPC client in ledger.New() from the existing grpc.ClientConn

Signature Encoding

  • Add proper DER signature encoding to pkg/keys/canton_keys.go -- current Sign() returns raw R||S (64 bytes) despite the comment saying "DER format". Add a SignDER() method producing ASN.1 DER-encoded ECDSA signatures as Canton expects.

Prepare/Execute Helper

  • Create prepareAndExecuteAsUser() helper in pkg/cantonsdk/token/client.go that:
    1. Calls PrepareSubmission via the ledger's Interactive() client
    2. Signs the returned prepared_transaction_hash with a provided private key (secp256k1 ECDSA-SHA256, DER format)
    3. Constructs PartySignatures with the party ID and DER signature
    4. Calls ExecuteSubmissionAndWait with the prepared transaction + signatures
  • Wire into transferHolding() (line 405) as an alternative submission path when a signing key is provided

Validation

  • Test PrepareSubmission + ExecuteSubmission round-trip against Canton 3.4.8
  • Confirm Interactive Submission works for internal parties (stepping stone before external party migration)
  • Verify signature format compatibility (DER-encoded secp256k1 with SIGNING_ALGORITHM_SPEC_EC_DSA_SHA_256)

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

Metadata

Metadata

Assignees

Labels

Canton LoopCanton Loop integrationPriority: P1Added to issues and PRs relating to a high severity bugs.Type: FeatureAdded to issues and PRs to identify that the change is a new feature.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions