Problem
The middleware currently uses AllocateParty (internal parties) to create a new Canton party for every registered user. Internal parties are fully managed by the participant node -- the node generates and holds signing keys. Canton has a ~200 internal party limit per participant node, making this a hard scalability blocker.
Canton Loop Wallet uses external parties (AllocateExternalParty), which have no practical limit. External parties require the Interactive Submission API (prepare/sign/execute) which is implemented in #113.
Solution
Switch user party allocation from internal to external while keeping the custodial model (server still generates and holds keys, signs via InteractiveSubmission server-side). The relayer/issuer party remains internal (uses only 1 of the 200 slots).
Registration Flow Change
- Current:
AllocateParty(hint) → GrantCanActAs(partyID) → standard submission
- Target:
GenerateExternalPartyTopology(pubKey) → sign topology → AllocateExternalParty(signedTxs) → InteractiveSubmission
Scope of Changes
Only TransferAsUser uses the user's party in ActAs. All other operations (mint, burn, deposit, withdrawal, fingerprint mapping) use the RelayerParty and remain unchanged. This keeps the migration focused and low-risk.
Tasks
Files Affected
| File |
Change |
pkg/canton/client.go |
Add AllocateExternalPartyForUser(), modify TransferAsUser() |
pkg/registration/handler.go |
Replace AllocateParty → AllocateExternalPartyForUser, remove GrantCanActAs |
Risks
Related Issues
Problem
The middleware currently uses
AllocateParty(internal parties) to create a new Canton party for every registered user. Internal parties are fully managed by the participant node -- the node generates and holds signing keys. Canton has a ~200 internal party limit per participant node, making this a hard scalability blocker.Canton Loop Wallet uses external parties (
AllocateExternalParty), which have no practical limit. External parties require the Interactive Submission API (prepare/sign/execute) which is implemented in #113.Solution
Switch user party allocation from internal to external while keeping the custodial model (server still generates and holds keys, signs via InteractiveSubmission server-side). The relayer/issuer party remains internal (uses only 1 of the 200 slots).
Registration Flow Change
AllocateParty(hint)→GrantCanActAs(partyID)→ standard submissionGenerateExternalPartyTopology(pubKey)→ sign topology →AllocateExternalParty(signedTxs)→ InteractiveSubmissionScope of Changes
Only
TransferAsUseruses the user's party inActAs. All other operations (mint, burn, deposit, withdrawal, fingerprint mapping) use the RelayerParty and remain unchanged. This keeps the migration focused and low-risk.Tasks
AllocateExternalPartyForUser()inpkg/canton/client.goGenerateExternalPartyTopology(synchronizer, partyHint, signingPublicKey)(stubs already exist inpkg/canton/lapi/v2/admin/)multi_hashwith user's private keyAllocateExternalParty(synchronizer, signedTopologyTxs)handleWeb3Registrationinpkg/registration/handler.goto useAllocateExternalPartyForUserinstead ofAllocatePartyGrantCanActAsfromhandleWeb3Registration(not needed with InteractiveSubmission)GrantCanActAsfromhandleCantonNativeRegistration(doesn't work for external parties)TransferAsUserto useprepareAndExecuteAsUser()from Interactive Submission API infrastructure (prepare/sign/execute) #113 instead ofCommandService.SubmitAndWaitFiles Affected
pkg/canton/client.goAllocateExternalPartyForUser(), modifyTransferAsUser()pkg/registration/handler.goAllocateParty→AllocateExternalPartyForUser, removeGrantCanActAsRisks
Related Issues