fixed serialization/deserialization
This commit is contained in:
154
api/pkg/chain/asset.go
Normal file
154
api/pkg/chain/asset.go
Normal file
@@ -0,0 +1,154 @@
|
||||
package chain
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/tech/sendico/pkg/merrors"
|
||||
chainv1 "github.com/tech/sendico/pkg/proto/gateway/chain/v1"
|
||||
)
|
||||
|
||||
func AssetString(asset *chainv1.Asset) string {
|
||||
if asset == nil {
|
||||
return ""
|
||||
}
|
||||
symbol := strings.ToUpper(strings.TrimSpace(asset.GetTokenSymbol()))
|
||||
if symbol == "" {
|
||||
return ""
|
||||
}
|
||||
suffix := assetSuffix(asset.GetChain())
|
||||
if suffix == "" {
|
||||
return symbol
|
||||
}
|
||||
return symbol + "-" + suffix
|
||||
}
|
||||
|
||||
func ParseAsset(assetString, network, tokenSymbol, contractAddress string) (*chainv1.Asset, error) {
|
||||
token := strings.TrimSpace(tokenSymbol)
|
||||
net := strings.TrimSpace(network)
|
||||
contract := strings.TrimSpace(contractAddress)
|
||||
|
||||
if token == "" {
|
||||
token = TokenFromAssetString(assetString)
|
||||
}
|
||||
if net == "" {
|
||||
net = NetworkFromAssetString(assetString)
|
||||
}
|
||||
if token == "" {
|
||||
return nil, merrors.InvalidArgument("asset: token_symbol is required")
|
||||
}
|
||||
chain := NetworkFromString(net)
|
||||
if chain == chainv1.ChainNetwork_CHAIN_NETWORK_UNSPECIFIED {
|
||||
return nil, merrors.InvalidArgument("asset: network is required")
|
||||
}
|
||||
return &chainv1.Asset{
|
||||
Chain: chain,
|
||||
TokenSymbol: strings.ToUpper(token),
|
||||
ContractAddress: strings.ToLower(contract),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func TokenFromAssetString(asset string) string {
|
||||
trimmed := strings.TrimSpace(asset)
|
||||
if trimmed == "" {
|
||||
return ""
|
||||
}
|
||||
if idx := strings.Index(trimmed, "-"); idx > 0 {
|
||||
return trimmed[:idx]
|
||||
}
|
||||
return trimmed
|
||||
}
|
||||
|
||||
func NetworkFromAssetString(asset string) string {
|
||||
trimmed := strings.TrimSpace(asset)
|
||||
if trimmed == "" {
|
||||
return ""
|
||||
}
|
||||
idx := strings.Index(trimmed, "-")
|
||||
if idx < 0 {
|
||||
return ""
|
||||
}
|
||||
return strings.TrimSpace(trimmed[idx+1:])
|
||||
}
|
||||
|
||||
func NetworkName(chain chainv1.ChainNetwork) string {
|
||||
if chain == chainv1.ChainNetwork_CHAIN_NETWORK_UNSPECIFIED {
|
||||
return ""
|
||||
}
|
||||
if name, ok := chainv1.ChainNetwork_name[int32(chain)]; ok {
|
||||
return strings.TrimPrefix(name, "CHAIN_NETWORK_")
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func NetworkAlias(chain chainv1.ChainNetwork) string {
|
||||
switch chain {
|
||||
case chainv1.ChainNetwork_CHAIN_NETWORK_ETHEREUM_MAINNET:
|
||||
return "ETH"
|
||||
case chainv1.ChainNetwork_CHAIN_NETWORK_TRON_MAINNET:
|
||||
return "TRON"
|
||||
case chainv1.ChainNetwork_CHAIN_NETWORK_TRON_NILE:
|
||||
return "TRON_NILE"
|
||||
case chainv1.ChainNetwork_CHAIN_NETWORK_ARBITRUM_ONE:
|
||||
return "ARBITRUM"
|
||||
default:
|
||||
name := NetworkName(chain)
|
||||
if name == "" {
|
||||
fallback := strings.TrimPrefix(strings.TrimSpace(chain.String()), "CHAIN_NETWORK_")
|
||||
return strings.ToUpper(fallback)
|
||||
}
|
||||
return strings.ToUpper(name)
|
||||
}
|
||||
}
|
||||
|
||||
func NetworkFromString(value string) chainv1.ChainNetwork {
|
||||
normalized := normalizeNetworkString(value)
|
||||
if normalized == "" {
|
||||
return chainv1.ChainNetwork_CHAIN_NETWORK_UNSPECIFIED
|
||||
}
|
||||
if val, ok := chainv1.ChainNetwork_value[normalized]; ok {
|
||||
return chainv1.ChainNetwork(val)
|
||||
}
|
||||
switch normalized {
|
||||
case "ETH", "ETHEREUM", "ETH_MAINNET":
|
||||
return chainv1.ChainNetwork_CHAIN_NETWORK_ETHEREUM_MAINNET
|
||||
case "TRON":
|
||||
return chainv1.ChainNetwork_CHAIN_NETWORK_TRON_MAINNET
|
||||
case "TRON_NILE":
|
||||
return chainv1.ChainNetwork_CHAIN_NETWORK_TRON_NILE
|
||||
case "ARB", "ARBITRUM":
|
||||
return chainv1.ChainNetwork_CHAIN_NETWORK_ARBITRUM_ONE
|
||||
}
|
||||
if !strings.HasPrefix(normalized, "CHAIN_NETWORK_") {
|
||||
normalized = "CHAIN_NETWORK_" + normalized
|
||||
}
|
||||
if val, ok := chainv1.ChainNetwork_value[normalized]; ok {
|
||||
return chainv1.ChainNetwork(val)
|
||||
}
|
||||
return chainv1.ChainNetwork_CHAIN_NETWORK_UNSPECIFIED
|
||||
}
|
||||
|
||||
func normalizeNetworkString(value string) string {
|
||||
trimmed := strings.TrimSpace(value)
|
||||
if trimmed == "" {
|
||||
return ""
|
||||
}
|
||||
normalized := strings.ToUpper(trimmed)
|
||||
normalized = strings.ReplaceAll(normalized, " ", "_")
|
||||
normalized = strings.ReplaceAll(normalized, "-", "_")
|
||||
return normalized
|
||||
}
|
||||
|
||||
func assetSuffix(chain chainv1.ChainNetwork) string {
|
||||
switch chain {
|
||||
case chainv1.ChainNetwork_CHAIN_NETWORK_ETHEREUM_MAINNET:
|
||||
return "ETH"
|
||||
case chainv1.ChainNetwork_CHAIN_NETWORK_ARBITRUM_ONE:
|
||||
return "ARB"
|
||||
case chainv1.ChainNetwork_CHAIN_NETWORK_TRON_MAINNET:
|
||||
return "TRC20"
|
||||
case chainv1.ChainNetwork_CHAIN_NETWORK_TRON_NILE:
|
||||
return "TRC20"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
55
api/pkg/chain/asset_test.go
Normal file
55
api/pkg/chain/asset_test.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package chain
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
chainv1 "github.com/tech/sendico/pkg/proto/gateway/chain/v1"
|
||||
)
|
||||
|
||||
func TestNetworkName(t *testing.T) {
|
||||
require.Equal(t, "TRON_MAINNET", NetworkName(chainv1.ChainNetwork_CHAIN_NETWORK_TRON_MAINNET))
|
||||
require.Equal(t, "", NetworkName(chainv1.ChainNetwork_CHAIN_NETWORK_UNSPECIFIED))
|
||||
}
|
||||
|
||||
func TestNetworkAlias(t *testing.T) {
|
||||
require.Equal(t, "ETH", NetworkAlias(chainv1.ChainNetwork_CHAIN_NETWORK_ETHEREUM_MAINNET))
|
||||
require.Equal(t, "TRON", NetworkAlias(chainv1.ChainNetwork_CHAIN_NETWORK_TRON_MAINNET))
|
||||
require.Equal(t, "TRON_NILE", NetworkAlias(chainv1.ChainNetwork_CHAIN_NETWORK_TRON_NILE))
|
||||
require.Equal(t, "ARBITRUM", NetworkAlias(chainv1.ChainNetwork_CHAIN_NETWORK_ARBITRUM_ONE))
|
||||
require.Equal(t, "UNSPECIFIED", NetworkAlias(chainv1.ChainNetwork_CHAIN_NETWORK_UNSPECIFIED))
|
||||
}
|
||||
|
||||
func TestNetworkFromString(t *testing.T) {
|
||||
require.Equal(t, chainv1.ChainNetwork_CHAIN_NETWORK_TRON_MAINNET, NetworkFromString("TRON_MAINNET"))
|
||||
require.Equal(t, chainv1.ChainNetwork_CHAIN_NETWORK_TRON_MAINNET, NetworkFromString("CHAIN_NETWORK_TRON_MAINNET"))
|
||||
require.Equal(t, chainv1.ChainNetwork_CHAIN_NETWORK_TRON_MAINNET, NetworkFromString("tron mainnet"))
|
||||
require.Equal(t, chainv1.ChainNetwork_CHAIN_NETWORK_TRON_MAINNET, NetworkFromString("tron-mainnet"))
|
||||
require.Equal(t, chainv1.ChainNetwork_CHAIN_NETWORK_TRON_MAINNET, NetworkFromString("TRON"))
|
||||
require.Equal(t, chainv1.ChainNetwork_CHAIN_NETWORK_ETHEREUM_MAINNET, NetworkFromString("ETH"))
|
||||
require.Equal(t, chainv1.ChainNetwork_CHAIN_NETWORK_ARBITRUM_ONE, NetworkFromString("ARBITRUM"))
|
||||
require.Equal(t, chainv1.ChainNetwork_CHAIN_NETWORK_UNSPECIFIED, NetworkFromString(""))
|
||||
}
|
||||
|
||||
func TestAssetString(t *testing.T) {
|
||||
asset := &chainv1.Asset{
|
||||
Chain: chainv1.ChainNetwork_CHAIN_NETWORK_TRON_MAINNET,
|
||||
TokenSymbol: "usdt",
|
||||
}
|
||||
require.Equal(t, "USDT-TRC20", AssetString(asset))
|
||||
}
|
||||
|
||||
func TestParseAsset(t *testing.T) {
|
||||
asset, err := ParseAsset("USDT-TRC20", "TRON_MAINNET", "", "")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, chainv1.ChainNetwork_CHAIN_NETWORK_TRON_MAINNET, asset.GetChain())
|
||||
require.Equal(t, "USDT", asset.GetTokenSymbol())
|
||||
require.Equal(t, "", asset.GetContractAddress())
|
||||
|
||||
asset, err = ParseAsset("USDT-TRC20", "CHAIN_NETWORK_TRON_MAINNET", "", "")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, chainv1.ChainNetwork_CHAIN_NETWORK_TRON_MAINNET, asset.GetChain())
|
||||
|
||||
_, err = ParseAsset("USDT-TRC20", "", "USDT", "")
|
||||
require.Error(t, err)
|
||||
}
|
||||
Reference in New Issue
Block a user