From e3f51866e8f5623e3fd242a3c4411788ec01baab Mon Sep 17 00:00:00 2001 From: Rohit Narurkar Date: Wed, 7 Jul 2021 14:11:33 +0400 Subject: [PATCH 1/3] feat: add asset type --- multichain.go | 65 +++++++++++++++++++++++++++++++++++++++++++--- multichain_test.go | 34 ++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 3 deletions(-) diff --git a/multichain.go b/multichain.go index a56c221a..a90fe4d0 100644 --- a/multichain.go +++ b/multichain.go @@ -115,6 +115,9 @@ const ( SOL = Asset("SOL") // Solana ZEC = Asset("ZEC") // Zcash + REN = Asset("REN") // Ren + USDC = Asset("USDC") // Circle USD + // These assets are defined separately because they are mock assets. These // assets should only be used for testing. @@ -123,10 +126,45 @@ const ( UMOCK = Asset("UMOCK") // UTXO-based mock asset ) +// AssetType represents the type of asset, whether native-asset of an account +// chain or a token on an account chain. +type AssetType string + +const ( + // AssetTypeNative is an identifier for all the native assets of account based + // chains namely. For instance, ETH for Ethereum, BNB for BinanceSmartChain. + AssetTypeNative = AssetType("NativeAsset") + + // AssetTypeToken is an identifier for all tokens (ERC20, BEP20) deployed on + // programmable account-based chains. For instance, REN is an ERC-20 token on + // Ethereum, USDC is an ERC-20 token on Ethereum. + AssetTypeToken = AssetType("TokenAsset") +) + +// SizeHint returns the number of bytes required to represent the asset type in +// binary. +func (assetType AssetType) SizeHint() int { + return surge.SizeHintString(string(assetType)) +} + +// Marshal the asset type to binary. You should not call this function directly, +// unless you are implementing marshalling for a container type. +func (assetType AssetType) Marshal(buf []byte, rem int) ([]byte, int, error) { + return surge.MarshalString(string(assetType), buf, rem) +} + +// Unmarshal the asset type from binary. You should not call this function +// directly, unless you are implementing unmarshalling for a container type. +func (assetType *AssetType) Unmarshal(buf []byte, rem int) ([]byte, int, error) { + return surge.UnmarshalString((*string)(assetType), buf, rem) +} + // OriginChain returns the chain upon which the asset originates. For example, // the origin chain of BTC is Bitcoin. func (asset Asset) OriginChain() Chain { switch asset { + case ArbETH: + return Arbitrum case AVAX: return Avalanche case BCH: @@ -151,12 +189,14 @@ func (asset Asset) OriginChain() Chain { return Terra case MATIC: return Polygon + case REN: + return Ethereum case SOL: return Solana + case USDC: + return Ethereum case ZEC: return Zcash - case ArbETH: - return Arbitrum // These assets are handled separately because they are mock assets. These // assets should only be used for testing. @@ -178,7 +218,7 @@ func (asset Asset) ChainType() ChainType { switch asset { case BCH, BTC, DGB, DOGE, ZEC: return ChainTypeUTXOBased - case ArbETH, AVAX, BNB, ETH, FIL, FTM, GLMR, LUNA, MATIC, SOL: + case ArbETH, AVAX, BNB, ETH, FIL, FTM, GLMR, LUNA, MATIC, REN, SOL, USDC: return ChainTypeAccountBased // These assets are handled separately because they are mock assets. These @@ -194,6 +234,25 @@ func (asset Asset) ChainType() ChainType { } } +// Type returns the asset-type (Native or Token) for the given asset. +func (asset Asset) Type() AssetType { + switch asset { + case ArbETH, AVAX, BNB, ETH, FTM, GLMR, MATIC, SOL: + return AssetTypeNative + case REN, USDC: + return AssetTypeToken + + // These assets are handled separately because they are mock assets. These + // assets should only be used for testing. + + case AMOCK1, AMOCK2: + return AssetTypeNative + + default: + return AssetType("") + } +} + // SizeHint returns the number of bytes required to represent the asset in // binary. func (asset Asset) SizeHint() int { diff --git a/multichain_test.go b/multichain_test.go index 973d9a4c..ce2d1379 100644 --- a/multichain_test.go +++ b/multichain_test.go @@ -193,6 +193,40 @@ var _ = Describe("Multichain", func() { }) } }) + + Context("Assets are declared appropriately", func() { + nativeAssets := []multichain.Asset{ + multichain.ArbETH, multichain.AVAX, multichain.BNB, multichain.ETH, + multichain.FTM, multichain.GLMR, multichain.MATIC, multichain.SOL, + } + tokenAssets := []struct { + asset multichain.Asset + chain multichain.Chain + }{ + { + multichain.REN, + multichain.Ethereum, + }, + { + multichain.USDC, + multichain.Ethereum, + }, + } + + for _, asset := range nativeAssets { + asset := asset + Specify(fmt.Sprintf("Asset=%v should be supported", asset), func() { + Expect(asset.Type()).To(Equal(multichain.AssetTypeNative)) + }) + } + for _, asset := range tokenAssets { + asset := asset + Specify(fmt.Sprintf("Asset=%v should be supported", asset.asset), func() { + Expect(asset.asset.Type()).To(Equal(multichain.AssetTypeToken)) + Expect(asset.asset.OriginChain()).To(Equal(asset.chain)) + }) + } + }) }) // From 21148ed39ff615a968322b48703c5ee49766591a Mon Sep 17 00:00:00 2001 From: Rohit Narurkar Date: Thu, 8 Jul 2021 11:54:52 +0400 Subject: [PATCH 2/3] feat: add a mock asset that is of token type --- multichain.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/multichain.go b/multichain.go index a90fe4d0..d611eb35 100644 --- a/multichain.go +++ b/multichain.go @@ -123,6 +123,7 @@ const ( AMOCK1 = Asset("AMOCK1") // Account-based mock asset AMOCK2 = Asset("AMOCK2") // Account-based mock asset + AMOCK3 = Asset("AMOCK3") // ERC-20 mock token asset on chain AccountMocker1 UMOCK = Asset("UMOCK") // UTXO-based mock asset ) @@ -201,7 +202,7 @@ func (asset Asset) OriginChain() Chain { // These assets are handled separately because they are mock assets. These // assets should only be used for testing. - case AMOCK1: + case AMOCK1, AMOCK3: return AccountMocker1 case AMOCK2: return AccountMocker2 @@ -224,7 +225,7 @@ func (asset Asset) ChainType() ChainType { // These assets are handled separately because they are mock assets. These // assets should only be used for testing. - case AMOCK1, AMOCK2: + case AMOCK1, AMOCK2, AMOCK3: return ChainTypeAccountBased case UMOCK: return ChainTypeUTXOBased @@ -247,6 +248,8 @@ func (asset Asset) Type() AssetType { case AMOCK1, AMOCK2: return AssetTypeNative + case AMOCK3: + return AssetTypeToken default: return AssetType("") From 88f80eec195a5d1bf04046aa45fb38adb98c404d Mon Sep 17 00:00:00 2001 From: Rohit Narurkar Date: Fri, 9 Jul 2021 01:05:32 +0400 Subject: [PATCH 3/3] fix: encoding to go via common address (checksummed format) --- chain/ethereum/address.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chain/ethereum/address.go b/chain/ethereum/address.go index dd3dae5b..eccbe57f 100644 --- a/chain/ethereum/address.go +++ b/chain/ethereum/address.go @@ -59,8 +59,8 @@ func (addressDecoder) DecodeAddress(encoded address.Address) (address.RawAddress } func (addressEncoder) EncodeAddress(rawAddr address.RawAddress) (address.Address, error) { - encodedAddr := common.Bytes2Hex([]byte(rawAddr)) - return address.Address(pack.NewString(encodedAddr)), nil + addr := common.BytesToAddress([]byte(rawAddr)) + return address.Address(addr.Hex()), nil } // An Address represents a public address on the Ethereum blockchain. It can be