feat: validate transfer recipient party#362
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces support for transferring tokens to external participant nodes (external transfers, e.g., USDCx) by adding an external_transfer configuration option and implementing a PartyExists check in the Canton identity client. The TransferService has been updated to validate recipient party IDs, ensuring unregistered parties are only allowed for external-transfer tokens and exist within the network topology. The review feedback highlights critical improvements to prevent potential nil pointer dereferences in PartyExists and TransferService, and suggests using errors.As in mapTransferErr to robustly extract gRPC status codes from wrapped errors.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #362 +/- ##
=======================================
Coverage ? 33.81%
=======================================
Files ? 163
Lines ? 12585
Branches ? 0
=======================================
Hits ? 4255
Misses ? 7989
Partials ? 341
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
dhyaniarun1993
left a comment
There was a problem hiding this comment.
Base branch seems incorrect
Transfers to a raw to_party_id previously failed at Canton submission with an opaque 500 when the recipient was unusable. Now validated up front in both the prepare/execute and custodial flows: - recipient registered in the user DB: any supported token - unregistered recipient + internal-only token (PROMPT/DEMO): 400 - unregistered recipient + external token (USDCx): party must exist in the participant topology (PartyManagementService.GetParties), else 400 Tokens are marked externally transferable via a new external_transfer flag in token config (set for USDCx). Remaining ledger rejections map to 400/502 instead of 500 via mapTransferErr.
Review feedback from gemini-code-assist.
Self-review findings: Aborted (Canton contention) now maps to Conflict like mapWithdrawErr; mapTransferErr wraps with the op before classification so logs keep prepare-vs-send context; checkRecipientParty no longer re-runs validatePartyID (both callers validate first).
16a8b03 to
c78d6c9
Compare
Problem
Transfers to a raw
to_party_idwere only syntax-checked. Two failure modes surfaced as 500s at Canton submission:Changes
Recipient validation (
pkg/transfer) — bothPrepare(raw party-id form) andSendCustodialnow runcheckRecipientPartyafter syntax/self checks:400 recipient party is not registered with this service and <TOKEN> does not support transfers to external parties.400 recipient party id is not known on the network. Topology lookup failure → 502.Token config — new
external_transferflag onsupported_tokensentries marks tokens transferable to unregistered/external parties. Set for USDCx in the deploy configs; PROMPT/DEMO default to internal-only.Topology check (
pkg/cantonsdk/identity) — newPartyExistson the identity client usingPartyManagementService.GetParties(unknown parties are omitted from the response rather than erroring).Error mapping safety net — Canton rejections from
PrepareTransfer/TransferByPartyIDnow mapInvalidArgument/NotFound/FailedPrecondition→ 400 andUnavailable/DeadlineExceeded→ 502 viamapTransferErr, so races that slip past the pre-checks no longer 500.Tests