chore(wallet)_: send type package simplification

- path processor constants moved to wallet constants
- FetchPrices and FindToken functions moved from send type package to router package
This commit is contained in:
Sale Djenic 2024-11-05 22:20:27 +01:00
parent b4f819d85c
commit bbc2686de9
32 changed files with 590 additions and 584 deletions

View File

@ -759,7 +759,7 @@ func (api *API) BuildTransactionsFromRoute(ctx context.Context, buildInputParams
// - call `SendRouterTransactionsWithSignatures` with the signatures of signed hashes from the previous step
//
// TODO: remove this struct once mobile switches to the new approach
func (api *API) ProceedWithTransactionsSignatures(ctx context.Context, signatures map[string]transfer.SignatureDetails) (*transfer.MultiTransactionCommandResult, error) {
func (api *API) ProceedWithTransactionsSignatures(ctx context.Context, signatures map[string]requests.SignatureDetails) (*transfer.MultiTransactionCommandResult, error) {
logutils.ZapLogger().Debug("[WalletAPI:: ProceedWithTransactionsSignatures] sign with signatures and send multi transaction")
return api.s.transactionManager.ProceedWithTransactionsSignatures(ctx, signatures)
}

View File

@ -13,7 +13,26 @@ type MultiTransactionIDType int64
const (
NoMultiTransactionID = MultiTransactionIDType(0)
HexAddressLength = 42
StatusDomain = "stateofus.eth"
EthDomain = "eth"
EthSymbol = "ETH"
SntSymbol = "SNT"
SttSymbol = "STT"
UsdcSymbol = "USDC"
HopSymbol = "HOP"
ProcessorTransferName = "Transfer"
ProcessorBridgeHopName = "Hop"
ProcessorBridgeCelerName = "CBridge"
ProcessorSwapParaswapName = "Paraswap"
ProcessorERC721Name = "ERC721Transfer"
ProcessorERC1155Name = "ERC1155Transfer"
ProcessorENSRegisterName = "ENSRegister"
ProcessorENSReleaseName = "ENSRelease"
ProcessorENSPublicKeyName = "ENSPublicKey"
ProcessorStickersBuyName = "StickersBuy"
)
type ChainID uint64

View File

@ -12,6 +12,14 @@ import (
"github.com/status-im/status-go/contracts/ierc20"
)
func IsProcessorBridge(name string) bool {
return name == ProcessorBridgeHopName || name == ProcessorBridgeCelerName
}
func IsProcessorSwap(name string) bool {
return name == ProcessorSwapParaswapName
}
func PackApprovalInputData(amountIn *big.Int, approvalContractAddress *common.Address) ([]byte, error) {
if approvalContractAddress == nil || *approvalContractAddress == ZeroAddress() {
return []byte{}, nil

View File

@ -8,7 +8,6 @@ import (
"github.com/status-im/status-go/errors"
walletCommon "github.com/status-im/status-go/services/wallet/common"
"github.com/status-im/status-go/services/wallet/router/fees"
"github.com/status-im/status-go/services/wallet/router/pathprocessor"
"github.com/status-im/status-go/services/wallet/router/sendtype"
"github.com/status-im/status-go/services/wallet/token"
)
@ -65,7 +64,7 @@ type RouteInputParams struct {
type RouterTestParams struct {
TokenFrom *token.Token
TokenPrices map[string]float64
EstimationMap map[string]pathprocessor.Estimation // [processor-name, estimation]
EstimationMap map[string]Estimation // [processor-name, estimation]
BonderFeeMap map[string]*big.Int // [token-symbol, bonder-fee]
SuggestedFees *fees.SuggestedFees
BaseFee *big.Int
@ -74,17 +73,22 @@ type RouterTestParams struct {
ApprovalL1Fee uint64
}
type Estimation struct {
Value uint64
Err error
}
func (i *RouteInputParams) Validate() error {
if i.SendType == sendtype.ENSRegister {
if i.Username == "" || i.PublicKey == "" {
return ErrENSRegisterRequiresUsernameAndPubKey
}
if i.TestnetMode {
if i.TokenID != pathprocessor.SttSymbol {
if i.TokenID != walletCommon.SttSymbol {
return ErrENSRegisterTestnetSTTOnly
}
} else {
if i.TokenID != pathprocessor.SntSymbol {
if i.TokenID != walletCommon.SntSymbol {
return ErrENSRegisterMainnetSNTOnly
}
}

View File

@ -1,8 +1,26 @@
package requests
import "github.com/status-im/status-go/services/wallet/transfer"
import "github.com/status-im/status-go/errors"
var (
ErrInvalidSignatureDetails = &errors.ErrorResponse{Code: errors.ErrorCode("WT-004"), Details: "invalid signature details"}
)
type RouterSendTransactionsParams struct {
Uuid string `json:"uuid"`
Signatures map[string]transfer.SignatureDetails `json:"signatures"`
Signatures map[string]SignatureDetails `json:"signatures"`
}
type SignatureDetails struct {
R string `json:"r"`
S string `json:"s"`
V string `json:"v"`
}
func (sd *SignatureDetails) Validate() error {
if len(sd.R) != 64 || len(sd.S) != 64 || len(sd.V) != 2 {
return ErrInvalidSignatureDetails
}
return nil
}

View File

@ -15,10 +15,10 @@ import (
status_common "github.com/status-im/status-go/common"
statusErrors "github.com/status-im/status-go/errors"
walletCommon "github.com/status-im/status-go/services/wallet/common"
"github.com/status-im/status-go/services/wallet/requests"
"github.com/status-im/status-go/services/wallet/responses"
"github.com/status-im/status-go/services/wallet/router"
"github.com/status-im/status-go/services/wallet/router/pathprocessor"
"github.com/status-im/status-go/services/wallet/router/sendtype"
"github.com/status-im/status-go/services/wallet/transfer"
"github.com/status-im/status-go/signal"
@ -117,9 +117,9 @@ func (m *Manager) SendRouterTransactionsWithSignatures(ctx context.Context, send
clearLocalData := true
if routeInputParams.SendType == sendtype.Swap {
// in case of swap don't clear local data if an approval is placed, but swap tx is not sent yet
if m.transactionManager.ApprovalRequiredForPath(pathprocessor.ProcessorSwapParaswapName) &&
m.transactionManager.ApprovalPlacedForPath(pathprocessor.ProcessorSwapParaswapName) &&
!m.transactionManager.TxPlacedForPath(pathprocessor.ProcessorSwapParaswapName) {
if m.transactionManager.ApprovalRequiredForPath(walletCommon.ProcessorSwapParaswapName) &&
m.transactionManager.ApprovalPlacedForPath(walletCommon.ProcessorSwapParaswapName) &&
!m.transactionManager.TxPlacedForPath(walletCommon.ProcessorSwapParaswapName) {
clearLocalData = false
}
}

View File

@ -11,6 +11,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/status-im/status-go/account"
"github.com/status-im/status-go/eth-node/types"
walletCommon "github.com/status-im/status-go/services/wallet/common"
)
func getSigner(chainID uint64, from types.Address, verifiedAccount *account.SelectedExtKey) bind.SignerFn {
@ -32,8 +33,9 @@ func makeKey(fromChain, toChain uint64, fromTokenSymbol, toTokenSymbol string, a
}
func getNameFromEnsUsername(ensUsername string) string {
if strings.HasSuffix(ensUsername, StatusDomain) {
return ensUsername[:len(ensUsername)-len(StatusDomain)]
suffix := "." + walletCommon.StatusDomain
if strings.HasSuffix(ensUsername, suffix) {
return ensUsername[:len(ensUsername)-len(suffix)]
}
return ensUsername
}

View File

@ -3,32 +3,4 @@ package pathprocessor
const (
IncreaseEstimatedGasFactor = 1.2
SevenDaysInSeconds = 60 * 60 * 24 * 7
StatusDomain = ".stateofus.eth"
EthDomain = ".eth"
EthSymbol = "ETH"
SntSymbol = "SNT"
SttSymbol = "STT"
UsdcSymbol = "USDC"
HopSymbol = "HOP"
ProcessorTransferName = "Transfer"
ProcessorBridgeHopName = "Hop"
ProcessorBridgeCelerName = "CBridge"
ProcessorSwapParaswapName = "Paraswap"
ProcessorERC721Name = "ERC721Transfer"
ProcessorERC1155Name = "ERC1155Transfer"
ProcessorENSRegisterName = "ENSRegister"
ProcessorENSReleaseName = "ENSRelease"
ProcessorENSPublicKeyName = "ENSPublicKey"
ProcessorStickersBuyName = "StickersBuy"
)
func IsProcessorBridge(name string) bool {
return name == ProcessorBridgeHopName || name == ProcessorBridgeCelerName
}
func IsProcessorSwap(name string) bool {
return name == ProcessorSwapParaswapName
}

View File

@ -4,6 +4,7 @@ import (
"context"
"github.com/status-im/status-go/errors"
walletCommon "github.com/status-im/status-go/services/wallet/common"
)
// Abbreviartion `WPP` for the error code stands for `Wallet Path Processor`
@ -69,25 +70,25 @@ func createErrorResponse(processorName string, err error) error {
var customErrResp *errors.ErrorResponse
switch processorName {
case ProcessorTransferName:
case walletCommon.ProcessorTransferName:
customErrResp = ErrTransferCustomError
case ProcessorERC721Name:
case walletCommon.ProcessorERC721Name:
customErrResp = ErrERC721TransferCustomError
case ProcessorERC1155Name:
case walletCommon.ProcessorERC1155Name:
customErrResp = ErrERC1155TransferCustomError
case ProcessorBridgeHopName:
case walletCommon.ProcessorBridgeHopName:
customErrResp = ErrBridgeHopCustomError
case ProcessorBridgeCelerName:
case walletCommon.ProcessorBridgeCelerName:
customErrResp = ErrBridgeCellerCustomError
case ProcessorSwapParaswapName:
case walletCommon.ProcessorSwapParaswapName:
customErrResp = ErrSwapParaswapCustomError
case ProcessorENSRegisterName:
case walletCommon.ProcessorENSRegisterName:
customErrResp = ErrENSRegisterCustomError
case ProcessorENSReleaseName:
case walletCommon.ProcessorENSReleaseName:
customErrResp = ErrENSReleaseCustomError
case ProcessorENSPublicKeyName:
case walletCommon.ProcessorENSPublicKeyName:
customErrResp = ErrENSPublicKeyCustomError
case ProcessorStickersBuyName:
case walletCommon.ProcessorStickersBuyName:
customErrResp = ErrStickersBuyCustomError
default:
return genericErrResp

View File

@ -7,6 +7,8 @@ import (
s_errors "github.com/status-im/status-go/errors"
walletCommon "github.com/status-im/status-go/services/wallet/common"
"github.com/stretchr/testify/require"
)
@ -15,17 +17,17 @@ func TestPlainError(t *testing.T) {
err := errors.New(errString)
processorNames := []string{
ProcessorTransferName,
ProcessorTransferName,
ProcessorBridgeHopName,
ProcessorBridgeCelerName,
ProcessorSwapParaswapName,
ProcessorERC721Name,
ProcessorERC1155Name,
ProcessorENSRegisterName,
ProcessorENSReleaseName,
ProcessorENSPublicKeyName,
ProcessorStickersBuyName,
walletCommon.ProcessorTransferName,
walletCommon.ProcessorTransferName,
walletCommon.ProcessorBridgeHopName,
walletCommon.ProcessorBridgeCelerName,
walletCommon.ProcessorSwapParaswapName,
walletCommon.ProcessorERC721Name,
walletCommon.ProcessorERC1155Name,
walletCommon.ProcessorENSRegisterName,
walletCommon.ProcessorENSReleaseName,
walletCommon.ProcessorENSPublicKeyName,
walletCommon.ProcessorStickersBuyName,
}
for _, processorName := range processorNames {
@ -62,7 +64,7 @@ func TestNonGenericErrorResponse(t *testing.T) {
Details: "Not Generic Error Response",
}
err := s_errors.CreateErrorResponseFromError(errResp)
ppErrResp := createErrorResponse(ProcessorTransferName, err)
ppErrResp := createErrorResponse(walletCommon.ProcessorTransferName, err)
castPPErrResp := ppErrResp.(*s_errors.ErrorResponse)
require.Equal(t, errResp.Code, castPPErrResp.Code)

View File

@ -11,6 +11,7 @@ import (
"github.com/status-im/status-go/account"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/services/wallet/requests"
"github.com/status-im/status-go/services/wallet/token"
"github.com/status-im/status-go/transactions"
)
@ -61,13 +62,8 @@ type ProcessorInputParams struct {
// for testing purposes
TestsMode bool
TestEstimationMap map[string]Estimation // [bridge-name, estimation]
TestEstimationMap map[string]requests.Estimation // [bridge-name, estimation]
TestBonderFeeMap map[string]*big.Int // [token-symbol, bonder-fee]
TestApprovalGasEstimation uint64
TestApprovalL1Fee uint64
}
type Estimation struct {
Value uint64
Err error
}

View File

@ -64,11 +64,11 @@ func NewCelerBridgeProcessor(rpcClient *rpc.Client, transactor transactions.Tran
}
func createBridgeCellerErrorResponse(err error) error {
return createErrorResponse(ProcessorBridgeCelerName, err)
return createErrorResponse(walletCommon.ProcessorBridgeCelerName, err)
}
func (s *CelerBridgeProcessor) Name() string {
return ProcessorBridgeCelerName
return walletCommon.ProcessorBridgeCelerName
}
func (s *CelerBridgeProcessor) estimateAmt(from, to *params.Network, amountIn *big.Int, symbol string) (*cbridge.EstimateAmtResponse, error) {
@ -147,11 +147,11 @@ func (s *CelerBridgeProcessor) AvailableFor(params ProcessorInputParams) (bool,
var fromAvailable *cbridge.Chain
var toAvailable *cbridge.Chain
for _, chain := range transferConfig.Chains {
if uint64(chain.GetId()) == params.FromChain.ChainID && chain.GasTokenSymbol == EthSymbol {
if uint64(chain.GetId()) == params.FromChain.ChainID && chain.GasTokenSymbol == walletCommon.EthSymbol {
fromAvailable = chain
}
if uint64(chain.GetId()) == params.ToChain.ChainID && chain.GasTokenSymbol == EthSymbol {
if uint64(chain.GetId()) == params.ToChain.ChainID && chain.GasTokenSymbol == walletCommon.EthSymbol {
toAvailable = chain
}
}

View File

@ -126,11 +126,11 @@ func NewHopBridgeProcessor(rpcClient rpc.ClientInterface, transactor transaction
}
func createBridgeHopErrorResponse(err error) error {
return createErrorResponse(ProcessorBridgeHopName, err)
return createErrorResponse(walletCommon.ProcessorBridgeHopName, err)
}
func (h *HopBridgeProcessor) Name() string {
return ProcessorBridgeHopName
return walletCommon.ProcessorBridgeHopName
}
func (h *HopBridgeProcessor) Clear() {
@ -164,7 +164,7 @@ func (c *HopBridgeProcessor) getAppropriateABI(contractType string, chainID uint
if token.IsNative() {
return abi.JSON(strings.NewReader(hopL1EthBridge.HopL1EthBridgeABI))
}
if token.Symbol == HopSymbol {
if token.Symbol == walletCommon.HopSymbol {
return abi.JSON(strings.NewReader(hopL1HopBridge.HopL1HopBridgeABI))
}
return abi.JSON(strings.NewReader(hopL1Erc20Bridge.HopL1Erc20BridgeABI))
@ -575,7 +575,7 @@ func (h *HopBridgeProcessor) sendL1BridgeTx(contractAddress common.Address, ethC
walletCommon.ZeroBigIntValue())
}
if token.Symbol == HopSymbol {
if token.Symbol == walletCommon.HopSymbol {
contractInstance, err := hopL1HopBridge.NewHopL1HopBridge(
contractAddress,
ethClient,

View File

@ -36,11 +36,11 @@ func NewENSPublicKeyProcessor(rpcClient *rpc.Client, transactor transactions.Tra
}
func createENSPublicKeyErrorResponse(err error) error {
return createErrorResponse(ProcessorENSPublicKeyName, err)
return createErrorResponse(walletCommon.ProcessorENSPublicKeyName, err)
}
func (s *ENSPublicKeyProcessor) Name() string {
return ProcessorENSPublicKeyName
return walletCommon.ProcessorENSPublicKeyName
}
func (s *ENSPublicKeyProcessor) AvailableFor(params ProcessorInputParams) (bool, error) {

View File

@ -38,11 +38,11 @@ func NewENSRegisterProcessor(rpcClient *rpc.Client, transactor transactions.Tran
}
func createENSRegisterProcessorErrorResponse(err error) error {
return createErrorResponse(ProcessorENSRegisterName, err)
return createErrorResponse(walletCommon.ProcessorENSRegisterName, err)
}
func (s *ENSRegisterProcessor) Name() string {
return ProcessorENSRegisterName
return walletCommon.ProcessorENSRegisterName
}
func (s *ENSRegisterProcessor) GetPriceForRegisteringEnsName(chainID uint64) (*big.Int, error) {

View File

@ -36,11 +36,11 @@ func NewENSReleaseProcessor(rpcClient *rpc.Client, transactor transactions.Trans
}
func createENSReleaseErrorResponse(err error) error {
return createErrorResponse(ProcessorENSReleaseName, err)
return createErrorResponse(walletCommon.ProcessorENSReleaseName, err)
}
func (s *ENSReleaseProcessor) Name() string {
return ProcessorENSReleaseName
return walletCommon.ProcessorENSReleaseName
}
func (s *ENSReleaseProcessor) AvailableFor(params ProcessorInputParams) (bool, error) {

View File

@ -36,11 +36,11 @@ func NewERC1155Processor(rpcClient *rpc.Client, transactor transactions.Transact
}
func createERC1155ErrorResponse(err error) error {
return createErrorResponse(ProcessorERC1155Name, err)
return createErrorResponse(walletCommon.ProcessorERC1155Name, err)
}
func (s *ERC1155Processor) Name() string {
return ProcessorERC1155Name
return walletCommon.ProcessorERC1155Name
}
func (s *ERC1155Processor) AvailableFor(params ProcessorInputParams) (bool, error) {

View File

@ -43,11 +43,11 @@ func NewERC721Processor(rpcClient *rpc.Client, transactor transactions.Transacto
}
func createERC721ErrorResponse(err error) error {
return createErrorResponse(ProcessorERC721Name, err)
return createErrorResponse(walletCommon.ProcessorERC721Name, err)
}
func (s *ERC721Processor) Name() string {
return ProcessorERC721Name
return walletCommon.ProcessorERC721Name
}
func (s *ERC721Processor) AvailableFor(params ProcessorInputParams) (bool, error) {

View File

@ -35,11 +35,11 @@ func NewStickersBuyProcessor(rpcClient *rpc.Client, transactor transactions.Tran
}
func createStickersBuyErrorResponse(err error) error {
return createErrorResponse(ProcessorStickersBuyName, err)
return createErrorResponse(walletCommon.ProcessorStickersBuyName, err)
}
func (s *StickersBuyProcessor) Name() string {
return ProcessorStickersBuyName
return walletCommon.ProcessorStickersBuyName
}
func (s *StickersBuyProcessor) AvailableFor(params ProcessorInputParams) (bool, error) {

View File

@ -76,11 +76,11 @@ func createSwapParaswapErrorResponse(err error) error {
case "ESTIMATED_LOSS_GREATER_THAN_MAX_IMPACT":
return ErrPriceImpactTooHigh
}
return createErrorResponse(ProcessorSwapParaswapName, err)
return createErrorResponse(walletCommon.ProcessorSwapParaswapName, err)
}
func (s *SwapParaswapProcessor) Name() string {
return ProcessorSwapParaswapName
return walletCommon.ProcessorSwapParaswapName
}
func (s *SwapParaswapProcessor) Clear() {

View File

@ -36,10 +36,10 @@ func TestParaswapWithPartnerFee(t *testing.T) {
processor := NewSwapParaswapProcessor(nil, nil, nil)
fromToken := token.Token{
Symbol: EthSymbol,
Symbol: walletCommon.EthSymbol,
}
toToken := token.Token{
Symbol: UsdcSymbol,
Symbol: walletCommon.UsdcSymbol,
}
chainIDs := []uint64{walletCommon.EthereumMainnet, walletCommon.ArbitrumMainnet, walletCommon.OptimismMainnet, walletCommon.UnknownChainID}
@ -107,10 +107,10 @@ func TestParaswapErrors(t *testing.T) {
processor.paraswapClient = client
fromToken := token.Token{
Symbol: EthSymbol,
Symbol: walletCommon.EthSymbol,
}
toToken := token.Token{
Symbol: UsdcSymbol,
Symbol: walletCommon.UsdcSymbol,
}
chainID := walletCommon.EthereumMainnet

View File

@ -6,6 +6,7 @@ import (
"github.com/status-im/status-go/params"
walletCommon "github.com/status-im/status-go/services/wallet/common"
"github.com/status-im/status-go/services/wallet/requests"
"github.com/status-im/status-go/services/wallet/token"
"github.com/stretchr/testify/assert"
@ -43,10 +44,10 @@ var optimism = params.Network{
RelatedChainID: walletCommon.OptimismMainnet,
}
var testEstimationMap = map[string]Estimation{
ProcessorTransferName: {uint64(1000), nil},
ProcessorBridgeHopName: {uint64(5000), nil},
ProcessorSwapParaswapName: {uint64(2000), nil},
var testEstimationMap = map[string]requests.Estimation{
walletCommon.ProcessorTransferName: {Value: uint64(1000)},
walletCommon.ProcessorBridgeHopName: {Value: uint64(5000)},
walletCommon.ProcessorSwapParaswapName: {Value: uint64(2000)},
}
type expectedResult struct {
@ -67,15 +68,15 @@ func TestPathProcessors(t *testing.T) {
TestsMode: true,
},
expected: map[string]expectedResult{
ProcessorTransferName: {
walletCommon.ProcessorTransferName: {
expected: false,
expectedError: ErrNoChainSet,
},
ProcessorBridgeHopName: {
walletCommon.ProcessorBridgeHopName: {
expected: false,
expectedError: ErrNoChainSet,
},
ProcessorSwapParaswapName: {
walletCommon.ProcessorSwapParaswapName: {
expected: false,
expectedError: ErrNoChainSet,
},
@ -90,15 +91,15 @@ func TestPathProcessors(t *testing.T) {
TestEstimationMap: testEstimationMap,
},
expected: map[string]expectedResult{
ProcessorTransferName: {
walletCommon.ProcessorTransferName: {
expected: false,
expectedError: ErrNoTokenSet,
},
ProcessorBridgeHopName: {
walletCommon.ProcessorBridgeHopName: {
expected: false,
expectedError: ErrNoTokenSet,
},
ProcessorSwapParaswapName: {
walletCommon.ProcessorSwapParaswapName: {
expected: false,
expectedError: ErrToAndFromTokensMustBeSet,
},
@ -111,20 +112,20 @@ func TestPathProcessors(t *testing.T) {
FromChain: &mainnet,
ToChain: &mainnet,
FromToken: &token.Token{
Symbol: EthSymbol,
Symbol: walletCommon.EthSymbol,
},
TestEstimationMap: testEstimationMap,
},
expected: map[string]expectedResult{
ProcessorTransferName: {
walletCommon.ProcessorTransferName: {
expected: true,
expectedError: nil,
},
ProcessorBridgeHopName: {
walletCommon.ProcessorBridgeHopName: {
expected: false,
expectedError: ErrFromAndToChainsMustBeDifferent,
},
ProcessorSwapParaswapName: {
walletCommon.ProcessorSwapParaswapName: {
expected: false,
expectedError: ErrToAndFromTokensMustBeSet,
},
@ -137,23 +138,23 @@ func TestPathProcessors(t *testing.T) {
FromChain: &mainnet,
ToChain: &mainnet,
FromToken: &token.Token{
Symbol: EthSymbol,
Symbol: walletCommon.EthSymbol,
},
ToToken: &token.Token{
Symbol: EthSymbol,
Symbol: walletCommon.EthSymbol,
},
TestEstimationMap: testEstimationMap,
},
expected: map[string]expectedResult{
ProcessorTransferName: {
walletCommon.ProcessorTransferName: {
expected: false,
expectedError: ErrToTokenShouldNotBeSet,
},
ProcessorBridgeHopName: {
walletCommon.ProcessorBridgeHopName: {
expected: false,
expectedError: ErrToTokenShouldNotBeSet,
},
ProcessorSwapParaswapName: {
walletCommon.ProcessorSwapParaswapName: {
expected: false,
expectedError: ErrFromAndToTokensMustBeDifferent,
},
@ -166,23 +167,23 @@ func TestPathProcessors(t *testing.T) {
FromChain: &mainnet,
ToChain: &mainnet,
FromToken: &token.Token{
Symbol: EthSymbol,
Symbol: walletCommon.EthSymbol,
},
ToToken: &token.Token{
Symbol: UsdcSymbol,
Symbol: walletCommon.UsdcSymbol,
},
TestEstimationMap: testEstimationMap,
},
expected: map[string]expectedResult{
ProcessorTransferName: {
walletCommon.ProcessorTransferName: {
expected: false,
expectedError: ErrToTokenShouldNotBeSet,
},
ProcessorBridgeHopName: {
walletCommon.ProcessorBridgeHopName: {
expected: false,
expectedError: ErrToTokenShouldNotBeSet,
},
ProcessorSwapParaswapName: {
walletCommon.ProcessorSwapParaswapName: {
expected: true,
expectedError: nil,
},
@ -197,15 +198,15 @@ func TestPathProcessors(t *testing.T) {
TestEstimationMap: testEstimationMap,
},
expected: map[string]expectedResult{
ProcessorTransferName: {
walletCommon.ProcessorTransferName: {
expected: false,
expectedError: ErrNoTokenSet,
},
ProcessorBridgeHopName: {
walletCommon.ProcessorBridgeHopName: {
expected: false,
expectedError: ErrNoTokenSet,
},
ProcessorSwapParaswapName: {
walletCommon.ProcessorSwapParaswapName: {
expected: false,
expectedError: ErrFromAndToChainsMustBeSame,
},
@ -218,20 +219,20 @@ func TestPathProcessors(t *testing.T) {
FromChain: &mainnet,
ToChain: &optimism,
FromToken: &token.Token{
Symbol: EthSymbol,
Symbol: walletCommon.EthSymbol,
},
TestEstimationMap: testEstimationMap,
},
expected: map[string]expectedResult{
ProcessorTransferName: {
walletCommon.ProcessorTransferName: {
expected: false,
expectedError: nil,
},
ProcessorBridgeHopName: {
walletCommon.ProcessorBridgeHopName: {
expected: true,
expectedError: nil,
},
ProcessorSwapParaswapName: {
walletCommon.ProcessorSwapParaswapName: {
expected: false,
expectedError: ErrFromAndToChainsMustBeSame,
},
@ -244,23 +245,23 @@ func TestPathProcessors(t *testing.T) {
FromChain: &mainnet,
ToChain: &optimism,
FromToken: &token.Token{
Symbol: EthSymbol,
Symbol: walletCommon.EthSymbol,
},
ToToken: &token.Token{
Symbol: EthSymbol,
Symbol: walletCommon.EthSymbol,
},
TestEstimationMap: testEstimationMap,
},
expected: map[string]expectedResult{
ProcessorTransferName: {
walletCommon.ProcessorTransferName: {
expected: false,
expectedError: ErrToTokenShouldNotBeSet,
},
ProcessorBridgeHopName: {
walletCommon.ProcessorBridgeHopName: {
expected: false,
expectedError: ErrToTokenShouldNotBeSet,
},
ProcessorSwapParaswapName: {
walletCommon.ProcessorSwapParaswapName: {
expected: false,
expectedError: ErrFromAndToChainsMustBeSame,
},
@ -273,23 +274,23 @@ func TestPathProcessors(t *testing.T) {
FromChain: &mainnet,
ToChain: &optimism,
FromToken: &token.Token{
Symbol: EthSymbol,
Symbol: walletCommon.EthSymbol,
},
ToToken: &token.Token{
Symbol: UsdcSymbol,
Symbol: walletCommon.UsdcSymbol,
},
TestEstimationMap: testEstimationMap,
},
expected: map[string]expectedResult{
ProcessorTransferName: {
walletCommon.ProcessorTransferName: {
expected: false,
expectedError: ErrToTokenShouldNotBeSet,
},
ProcessorBridgeHopName: {
walletCommon.ProcessorBridgeHopName: {
expected: false,
expectedError: ErrToTokenShouldNotBeSet,
},
ProcessorSwapParaswapName: {
walletCommon.ProcessorSwapParaswapName: {
expected: false,
expectedError: ErrFromAndToChainsMustBeSame,
},
@ -302,11 +303,11 @@ func TestPathProcessors(t *testing.T) {
t.Run(fmt.Sprintf("%s[%s]", processorName, tt.name), func(t *testing.T) {
var processor PathProcessor
if processorName == ProcessorTransferName {
if processorName == walletCommon.ProcessorTransferName {
processor = NewTransferProcessor(nil, nil)
} else if processorName == ProcessorBridgeHopName {
} else if processorName == walletCommon.ProcessorBridgeHopName {
processor = NewHopBridgeProcessor(nil, nil, nil, nil)
} else if processorName == ProcessorSwapParaswapName {
} else if processorName == walletCommon.ProcessorSwapParaswapName {
processor = NewSwapParaswapProcessor(nil, nil, nil)
}
@ -325,8 +326,8 @@ func TestPathProcessors(t *testing.T) {
assert.Greater(t, estimatedGas, uint64(0))
input := tt.input
input.TestEstimationMap = map[string]Estimation{
"randomName": {10000, nil},
input.TestEstimationMap = map[string]requests.Estimation{
"randomName": {Value: 10000},
}
estimatedGas, err = processor.EstimateGas(input)
assert.Error(t, err)

View File

@ -27,11 +27,11 @@ func NewTransferProcessor(rpcClient *rpc.Client, transactor transactions.Transac
}
func createTransferErrorResponse(err error) error {
return createErrorResponse(ProcessorTransferName, err)
return createErrorResponse(walletCommon.ProcessorTransferName, err)
}
func (s *TransferProcessor) Name() string {
return ProcessorTransferName
return walletCommon.ProcessorTransferName
}
func (s *TransferProcessor) AvailableFor(params ProcessorInputParams) (bool, error) {

View File

@ -356,7 +356,7 @@ func (r *Router) prepareBalanceMapForTokenOnChains(ctx context.Context, input *r
for _, chain := range selectedFromChains {
// check token existence
token := input.SendType.FindToken(r.tokenManager, r.collectiblesService, input.AddrFrom, chain, input.TokenID)
token := findToken(input.SendType, r.tokenManager, r.collectiblesService, input.AddrFrom, chain, input.TokenID)
if token == nil {
chainError(chain.ChainID, input.TokenID, ErrTokenNotFound)
continue
@ -629,14 +629,14 @@ func (r *Router) resolveCandidates(ctx context.Context, input *requests.RouteInp
if testsMode {
token = input.TestParams.TokenFrom
} else {
token = input.SendType.FindToken(r.tokenManager, r.collectiblesService, input.AddrFrom, network, input.TokenID)
token = findToken(input.SendType, r.tokenManager, r.collectiblesService, input.AddrFrom, network, input.TokenID)
}
if token == nil {
continue
}
if input.SendType == sendtype.Swap {
toToken = input.SendType.FindToken(r.tokenManager, r.collectiblesService, common.Address{}, network, input.ToTokenID)
toToken = findToken(input.SendType, r.tokenManager, r.collectiblesService, common.Address{}, network, input.ToTokenID)
}
var fetchedFees *fees.SuggestedFees
@ -668,12 +668,12 @@ func (r *Router) resolveCandidates(ctx context.Context, input *requests.RouteInp
// 6. ...
//
// With the current routing algorithm atm we're not able to generate all possible routes.
if !input.SendType.CanUseProcessor(pProcessor) {
if !input.SendType.CanUseProcessor(pProcessor.Name()) {
continue
}
// if we're doing a single chain operation, we can skip bridge processors
if walletCommon.IsSingleChainOperation(selectedFromChains, selectedToChains) && pathprocessor.IsProcessorBridge(pProcessor.Name()) {
if walletCommon.IsSingleChainOperation(selectedFromChains, selectedToChains) && walletCommon.IsProcessorBridge(pProcessor.Name()) {
continue
}
@ -840,7 +840,7 @@ func (r *Router) checkBalancesForTheBestRoute(ctx context.Context, bestRoute rou
}
}
if path.ProcessorName == pathprocessor.ProcessorBridgeHopName {
if path.ProcessorName == walletCommon.ProcessorBridgeHopName {
if path.TxBonderFees.ToInt().Cmp(path.AmountOut.ToInt()) > 0 {
return hasPositiveBalance, ErrLowAmountInForHopBridge
}
@ -861,12 +861,12 @@ func (r *Router) checkBalancesForTheBestRoute(ctx context.Context, bestRoute rou
}
}
ethKey := makeBalanceKey(path.FromChain.ChainID, pathprocessor.EthSymbol)
ethKey := makeBalanceKey(path.FromChain.ChainID, walletCommon.EthSymbol)
if nativeBalance, ok := balanceMapCopy[ethKey]; ok {
if nativeBalance.Cmp(path.RequiredNativeBalance) == -1 {
err := &errors.ErrorResponse{
Code: ErrNotEnoughNativeBalance.Code,
Details: fmt.Sprintf(ErrNotEnoughNativeBalance.Details, pathprocessor.EthSymbol, path.FromChain.ChainID),
Details: fmt.Sprintf(ErrNotEnoughNativeBalance.Details, walletCommon.EthSymbol, path.FromChain.ChainID),
}
return hasPositiveBalance, err
}
@ -884,14 +884,14 @@ func (r *Router) resolveRoutes(ctx context.Context, input *requests.RouteInputPa
if input.TestsMode {
prices = input.TestParams.TokenPrices
} else {
prices, err = input.SendType.FetchPrices(r.marketManager, []string{input.TokenID, input.ToTokenID})
prices, err = fetchPrices(input.SendType, r.marketManager, []string{input.TokenID, input.ToTokenID})
if err != nil {
return nil, errors.CreateErrorResponseFromError(err)
}
}
tokenPrice := prices[input.TokenID]
nativeTokenPrice := prices[pathprocessor.EthSymbol]
nativeTokenPrice := prices[walletCommon.EthSymbol]
var allRoutes []routes.Route
suggestedRoutes, allRoutes = newSuggestedRoutes(input, candidates, prices)

View File

@ -4,6 +4,8 @@ import (
"context"
"errors"
"math/big"
"slices"
"strings"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
@ -13,7 +15,9 @@ import (
gaspriceoracle "github.com/status-im/status-go/contracts/gas-price-oracle"
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/services/wallet/bigint"
"github.com/status-im/status-go/services/wallet/collectibles"
walletCommon "github.com/status-im/status-go/services/wallet/common"
"github.com/status-im/status-go/services/wallet/market"
"github.com/status-im/status-go/services/wallet/router/fees"
"github.com/status-im/status-go/services/wallet/router/pathprocessor"
routs "github.com/status-im/status-go/services/wallet/router/routes"
@ -236,3 +240,53 @@ func (r *Router) cacluateFees(ctx context.Context, path *routs.Path, fetchedFees
return nil
}
func findToken(sendType sendtype.SendType, tokenManager *token.Manager, collectibles *collectibles.Service, account common.Address, network *params.Network, tokenID string) *token.Token {
if !sendType.IsCollectiblesTransfer() {
return tokenManager.FindToken(network, tokenID)
}
parts := strings.Split(tokenID, ":")
contractAddress := common.HexToAddress(parts[0])
collectibleTokenID, success := new(big.Int).SetString(parts[1], 10)
if !success {
return nil
}
uniqueID, err := collectibles.GetOwnedCollectible(walletCommon.ChainID(network.ChainID), account, contractAddress, collectibleTokenID)
if err != nil || uniqueID == nil {
return nil
}
return &token.Token{
Address: contractAddress,
Symbol: collectibleTokenID.String(),
Decimals: 0,
ChainID: network.ChainID,
}
}
func fetchPrices(sendType sendtype.SendType, marketManager *market.Manager, tokenIDs []string) (map[string]float64, error) {
nonUniqueSymbols := append(tokenIDs, "ETH")
// remove duplicate enteries
slices.Sort(nonUniqueSymbols)
symbols := slices.Compact(nonUniqueSymbols)
if sendType.IsCollectiblesTransfer() {
symbols = []string{"ETH"}
}
pricesMap, err := marketManager.GetOrFetchPrices(symbols, []string{"USD"}, market.MaxAgeInSecondsForFresh)
if err != nil {
return nil, err
}
prices := make(map[string]float64, 0)
for symbol, pricePerCurrency := range pricesMap {
prices[symbol] = pricePerCurrency["USD"].Price
}
if sendType.IsCollectiblesTransfer() {
for _, tokenID := range tokenIDs {
prices[tokenID] = 0
}
}
return prices, nil
}

File diff suppressed because it is too large Load Diff

View File

@ -2,16 +2,9 @@ package sendtype
import (
"math/big"
"slices"
"strings"
"github.com/ethereum/go-ethereum/common"
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/services/wallet/collectibles"
walletCommon "github.com/status-im/status-go/services/wallet/common"
"github.com/status-im/status-go/services/wallet/market"
"github.com/status-im/status-go/services/wallet/router/pathprocessor"
"github.com/status-im/status-go/services/wallet/token"
)
type SendType int
@ -40,79 +33,28 @@ func (s SendType) IsStickersTransfer() bool {
return s == StickersBuy
}
func (s SendType) FetchPrices(marketManager *market.Manager, tokenIDs []string) (map[string]float64, error) {
nonUniqueSymbols := append(tokenIDs, "ETH")
// remove duplicate enteries
slices.Sort(nonUniqueSymbols)
symbols := slices.Compact(nonUniqueSymbols)
if s.IsCollectiblesTransfer() {
symbols = []string{"ETH"}
}
pricesMap, err := marketManager.GetOrFetchPrices(symbols, []string{"USD"}, market.MaxAgeInSecondsForFresh)
if err != nil {
return nil, err
}
prices := make(map[string]float64, 0)
for symbol, pricePerCurrency := range pricesMap {
prices[symbol] = pricePerCurrency["USD"].Price
}
if s.IsCollectiblesTransfer() {
for _, tokenID := range tokenIDs {
prices[tokenID] = 0
}
}
return prices, nil
}
func (s SendType) FindToken(tokenManager *token.Manager, collectibles *collectibles.Service, account common.Address, network *params.Network, tokenID string) *token.Token {
if !s.IsCollectiblesTransfer() {
return tokenManager.FindToken(network, tokenID)
}
parts := strings.Split(tokenID, ":")
contractAddress := common.HexToAddress(parts[0])
collectibleTokenID, success := new(big.Int).SetString(parts[1], 10)
if !success {
return nil
}
uniqueID, err := collectibles.GetOwnedCollectible(walletCommon.ChainID(network.ChainID), account, contractAddress, collectibleTokenID)
if err != nil || uniqueID == nil {
return nil
}
return &token.Token{
Address: contractAddress,
Symbol: collectibleTokenID.String(),
Decimals: 0,
ChainID: network.ChainID,
}
}
// canUseProcessor is used to check if certain SendType can be used with a given path processor
func (s SendType) CanUseProcessor(p pathprocessor.PathProcessor) bool {
pathProcessorName := p.Name()
func (s SendType) CanUseProcessor(pathProcessorName string) bool {
switch s {
case Transfer:
return pathProcessorName == pathprocessor.ProcessorTransferName ||
pathprocessor.IsProcessorBridge(pathProcessorName)
return pathProcessorName == walletCommon.ProcessorTransferName ||
walletCommon.IsProcessorBridge(pathProcessorName)
case Bridge:
return pathprocessor.IsProcessorBridge(pathProcessorName)
return walletCommon.IsProcessorBridge(pathProcessorName)
case Swap:
return pathprocessor.IsProcessorSwap(pathProcessorName)
return walletCommon.IsProcessorSwap(pathProcessorName)
case ERC721Transfer:
return pathProcessorName == pathprocessor.ProcessorERC721Name
return pathProcessorName == walletCommon.ProcessorERC721Name
case ERC1155Transfer:
return pathProcessorName == pathprocessor.ProcessorERC1155Name
return pathProcessorName == walletCommon.ProcessorERC1155Name
case ENSRegister:
return pathProcessorName == pathprocessor.ProcessorENSRegisterName
return pathProcessorName == walletCommon.ProcessorENSRegisterName
case ENSRelease:
return pathProcessorName == pathprocessor.ProcessorENSReleaseName
return pathProcessorName == walletCommon.ProcessorENSReleaseName
case ENSSetPubKey:
return pathProcessorName == pathprocessor.ProcessorENSPublicKeyName
return pathProcessorName == walletCommon.ProcessorENSPublicKeyName
case StickersBuy:
return pathProcessorName == pathprocessor.ProcessorStickersBuyName
return pathProcessorName == walletCommon.ProcessorStickersBuyName
default:
return true
}
@ -121,7 +63,7 @@ func (s SendType) CanUseProcessor(p pathprocessor.PathProcessor) bool {
func (s SendType) ProcessZeroAmountInProcessor(amountIn *big.Int, amountOut *big.Int, processorName string) bool {
if amountIn.Cmp(walletCommon.ZeroBigIntValue()) == 0 {
if s == Transfer {
if processorName != pathprocessor.ProcessorTransferName {
if processorName != walletCommon.ProcessorTransferName {
return false
}
} else if s == Swap {

View File

@ -9,5 +9,4 @@ var (
ErrNoRoute = &errors.ErrorResponse{Code: errors.ErrorCode("WT-001"), Details: "no generated route"}
ErrNoTrsansactionsBeingBuilt = &errors.ErrorResponse{Code: errors.ErrorCode("WT-002"), Details: "no transactions being built"}
ErrMissingSignatureForTx = &errors.ErrorResponse{Code: errors.ErrorCode("WT-003"), Details: "missing signature for transaction %s"}
ErrInvalidSignatureDetails = &errors.ErrorResponse{Code: errors.ErrorCode("WT-004"), Details: "invalid signature details"}
)

View File

@ -17,6 +17,7 @@ import (
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/logutils"
wallet_common "github.com/status-im/status-go/services/wallet/common"
"github.com/status-im/status-go/services/wallet/requests"
"github.com/status-im/status-go/services/wallet/router/pathprocessor"
)
@ -72,7 +73,7 @@ func rowsToMultiTransactions(rows *sql.Rows) ([]*MultiTransaction, error) {
return multiTransactions, nil
}
func addSignaturesToTransactions(transactions map[common.Hash]*TransactionDescription, signatures map[string]SignatureDetails) error {
func addSignaturesToTransactions(transactions map[common.Hash]*TransactionDescription, signatures map[string]requests.SignatureDetails) error {
if len(transactions) == 0 {
return errors.New("no transactions to proceed with")
}

View File

@ -21,20 +21,6 @@ import (
"github.com/status-im/status-go/transactions"
)
type SignatureDetails struct {
R string `json:"r"`
S string `json:"s"`
V string `json:"v"`
}
func (sd *SignatureDetails) Validate() error {
if len(sd.R) != 64 || len(sd.S) != 64 || len(sd.V) != 2 {
return ErrInvalidSignatureDetails
}
return nil
}
// TODO: remove this struct once mobile switches to the new approach
type TransactionDescription struct {
chainID uint64

View File

@ -14,6 +14,7 @@ import (
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/logutils"
wallet_common "github.com/status-im/status-go/services/wallet/common"
"github.com/status-im/status-go/services/wallet/requests"
"github.com/status-im/status-go/services/wallet/router/pathprocessor"
"github.com/status-im/status-go/services/wallet/walletevent"
"github.com/status-im/status-go/signal"
@ -102,7 +103,7 @@ func (tm *TransactionManager) SendTransactions(ctx context.Context, multiTransac
}, nil
}
func (tm *TransactionManager) ProceedWithTransactionsSignatures(ctx context.Context, signatures map[string]SignatureDetails) (*MultiTransactionCommandResult, error) {
func (tm *TransactionManager) ProceedWithTransactionsSignatures(ctx context.Context, signatures map[string]requests.SignatureDetails) (*MultiTransactionCommandResult, error) {
if err := addSignaturesToTransactions(tm.transactionsForKeycardSigning, signatures); err != nil {
return nil, err
}

View File

@ -13,6 +13,7 @@ import (
"github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/eth-node/types"
walletCommon "github.com/status-im/status-go/services/wallet/common"
"github.com/status-im/status-go/services/wallet/requests"
"github.com/status-im/status-go/services/wallet/responses"
"github.com/status-im/status-go/services/wallet/router/pathprocessor"
"github.com/status-im/status-go/services/wallet/router/routes"
@ -178,13 +179,13 @@ func buildTxForPath(transactor transactions.TransactorIface, path *routes.Path,
if !path.FromToken.IsNative() {
sendArgs.Value = (*hexutil.Big)(big.NewInt(0))
if path.ProcessorName == pathprocessor.ProcessorTransferName ||
path.ProcessorName == pathprocessor.ProcessorStickersBuyName ||
path.ProcessorName == pathprocessor.ProcessorENSRegisterName ||
path.ProcessorName == pathprocessor.ProcessorENSReleaseName ||
path.ProcessorName == pathprocessor.ProcessorENSPublicKeyName ||
path.ProcessorName == pathprocessor.ProcessorERC721Name ||
path.ProcessorName == pathprocessor.ProcessorERC1155Name {
if path.ProcessorName == walletCommon.ProcessorTransferName ||
path.ProcessorName == walletCommon.ProcessorStickersBuyName ||
path.ProcessorName == walletCommon.ProcessorENSRegisterName ||
path.ProcessorName == walletCommon.ProcessorENSReleaseName ||
path.ProcessorName == walletCommon.ProcessorENSPublicKeyName ||
path.ProcessorName == walletCommon.ProcessorERC721Name ||
path.ProcessorName == walletCommon.ProcessorERC1155Name {
// TODO: update functions from `TransactorIface` to use `ToContractAddress` (as an address of the contract a transaction should be sent to)
// and `To` (as the destination address, recipient) of `SendTxArgs` struct appropriately
toContractAddr := types.Address(path.FromToken.Address)
@ -248,7 +249,7 @@ func (tm *TransactionManager) BuildTransactionsFromRoute(route routes.Route, pat
response.Hashes = append(response.Hashes, txDetails.ApprovalTxData.HashToSign)
// if approval is needed for swap, we cannot build the swap tx before the approval tx is mined
if path.ProcessorName == pathprocessor.ProcessorSwapParaswapName {
if path.ProcessorName == walletCommon.ProcessorSwapParaswapName {
continue
}
}
@ -264,7 +265,7 @@ func (tm *TransactionManager) BuildTransactionsFromRoute(route routes.Route, pat
return response, nil
}
func getSignatureForTxHash(txHash string, signatures map[string]SignatureDetails) ([]byte, error) {
func getSignatureForTxHash(txHash string, signatures map[string]requests.SignatureDetails) ([]byte, error) {
sigDetails, ok := signatures[txHash]
if !ok {
err := &errors.ErrorResponse{
@ -306,7 +307,7 @@ func validateAndAddSignature(txData *TransactionData, signatures map[string]Sign
return nil
}
func (tm *TransactionManager) ValidateAndAddSignaturesToRouterTransactions(signatures map[string]SignatureDetails) error {
func (tm *TransactionManager) ValidateAndAddSignaturesToRouterTransactions(signatures map[string]requests.SignatureDetails) error {
if len(tm.routerTransactions) == 0 {
return ErrNoTrsansactionsBeingBuilt
}
@ -365,7 +366,7 @@ func (tm *TransactionManager) SendRouterTransactions(ctx context.Context, multiT
transactions = append(transactions, response)
// if approval is needed for swap, then we need to wait for the approval tx to be mined before sending the swap tx
if desc.RouterPath.ProcessorName == pathprocessor.ProcessorSwapParaswapName {
if desc.RouterPath.ProcessorName == walletCommon.ProcessorSwapParaswapName {
continue
}
}