From 1ec6cd83861e4b1a7ef7ca620e9b336f9401d040 Mon Sep 17 00:00:00 2001 From: Stephan D Date: Fri, 26 Dec 2025 17:24:43 +0100 Subject: [PATCH] fixed address normalizatoin --- .../gateway/commands/transfer/destination.go | 5 +- api/gateway/chain/storage/model/transfer.go | 10 ++-- .../chain/storage/model/transfer_test.go | 50 +++++++++++++++++++ 3 files changed, 59 insertions(+), 6 deletions(-) create mode 100644 api/gateway/chain/storage/model/transfer_test.go diff --git a/api/gateway/chain/internal/service/gateway/commands/transfer/destination.go b/api/gateway/chain/internal/service/gateway/commands/transfer/destination.go index 15b77a4..9988013 100644 --- a/api/gateway/chain/internal/service/gateway/commands/transfer/destination.go +++ b/api/gateway/chain/internal/service/gateway/commands/transfer/destination.go @@ -58,7 +58,8 @@ func resolveDestination(ctx context.Context, deps Deps, dest *chainv1.TransferDe return model.TransferDestination{}, err } return model.TransferDestination{ - ExternalAddress: normalized, - Memo: strings.TrimSpace(dest.GetMemo()), + ExternalAddress: normalized, + ExternalAddressOriginal: external, + Memo: strings.TrimSpace(dest.GetMemo()), }, nil } diff --git a/api/gateway/chain/storage/model/transfer.go b/api/gateway/chain/storage/model/transfer.go index 1ee246b..fe4ecf6 100644 --- a/api/gateway/chain/storage/model/transfer.go +++ b/api/gateway/chain/storage/model/transfer.go @@ -28,9 +28,10 @@ type ServiceFee struct { } type TransferDestination struct { - ManagedWalletRef string `bson:"managedWalletRef,omitempty" json:"managedWalletRef,omitempty"` - ExternalAddress string `bson:"externalAddress,omitempty" json:"externalAddress,omitempty"` - Memo string `bson:"memo,omitempty" json:"memo,omitempty"` + ManagedWalletRef string `bson:"managedWalletRef,omitempty" json:"managedWalletRef,omitempty"` + ExternalAddress string `bson:"externalAddress,omitempty" json:"externalAddress,omitempty"` + ExternalAddressOriginal string `bson:"externalAddressOriginal,omitempty" json:"externalAddressOriginal,omitempty"` + Memo string `bson:"memo,omitempty" json:"memo,omitempty"` } // Transfer models an on-chain transfer orchestrated by the gateway. @@ -85,7 +86,8 @@ func (t *Transfer) Normalize() { t.TokenSymbol = strings.TrimSpace(strings.ToUpper(t.TokenSymbol)) t.ContractAddress = strings.TrimSpace(strings.ToLower(t.ContractAddress)) t.Destination.ManagedWalletRef = strings.TrimSpace(t.Destination.ManagedWalletRef) - t.Destination.ExternalAddress = strings.TrimSpace(strings.ToLower(t.Destination.ExternalAddress)) + t.Destination.ExternalAddress = normalizeWalletAddress(t.Destination.ExternalAddress) + t.Destination.ExternalAddressOriginal = strings.TrimSpace(t.Destination.ExternalAddressOriginal) t.Destination.Memo = strings.TrimSpace(t.Destination.Memo) t.ClientReference = strings.TrimSpace(t.ClientReference) } diff --git a/api/gateway/chain/storage/model/transfer_test.go b/api/gateway/chain/storage/model/transfer_test.go new file mode 100644 index 0000000..f48a38b --- /dev/null +++ b/api/gateway/chain/storage/model/transfer_test.go @@ -0,0 +1,50 @@ +package model + +import ( + "strings" + "testing" +) + +func TestTransferNormalizePreservesBase58ExternalAddress(t *testing.T) { + address := "TGBDXEg9rxSqGFJDcb889zqTjDwx1bmLRF" + transfer := &Transfer{ + IdempotencyKey: "idemp", + TransferRef: "ref", + OrganizationRef: "org", + SourceWalletRef: "wallet", + Network: "tron_mainnet", + TokenSymbol: "USDT", + Destination: TransferDestination{ + ExternalAddress: address, + ExternalAddressOriginal: address, + }, + } + + transfer.Normalize() + + if transfer.Destination.ExternalAddress != address { + t.Fatalf("expected external address to preserve case, got %q", transfer.Destination.ExternalAddress) + } + if transfer.Destination.ExternalAddressOriginal != address { + t.Fatalf("expected external address original to preserve case, got %q", transfer.Destination.ExternalAddressOriginal) + } +} + +func TestTransferNormalizeLowercasesHexExternalAddress(t *testing.T) { + address := "0xAABBCCDDEEFF00112233445566778899AABBCCDD" + transfer := &Transfer{ + Destination: TransferDestination{ + ExternalAddress: address, + ExternalAddressOriginal: address, + }, + } + + transfer.Normalize() + + if transfer.Destination.ExternalAddress != strings.ToLower(address) { + t.Fatalf("expected hex external address to be lowercased, got %q", transfer.Destination.ExternalAddress) + } + if transfer.Destination.ExternalAddressOriginal != address { + t.Fatalf("expected external address original to preserve case, got %q", transfer.Destination.ExternalAddressOriginal) + } +}