decred.org/dcrdex@v1.0.5/client/asset/polygon/polygon.go (about)

     1  // This code is available on the terms of the project LICENSE.md file,
     2  // also available online at https://blueoakcouncil.org/license/1.0.0.
     3  
     4  package polygon
     5  
     6  import (
     7  	"fmt"
     8  	"os/user"
     9  	"path/filepath"
    10  	"strconv"
    11  
    12  	"decred.org/dcrdex/client/asset"
    13  	"decred.org/dcrdex/client/asset/eth"
    14  	"decred.org/dcrdex/dex"
    15  	dexpolygon "decred.org/dcrdex/dex/networks/polygon"
    16  	"github.com/ethereum/go-ethereum/common"
    17  )
    18  
    19  func init() {
    20  	dexpolygon.MaybeReadSimnetAddrs()
    21  }
    22  
    23  func registerToken(tokenID uint32, desc string, nets ...dex.Network) {
    24  	token, found := dexpolygon.Tokens[tokenID]
    25  	if !found {
    26  		panic("token " + strconv.Itoa(int(tokenID)) + " not known")
    27  	}
    28  	netAddrs := make(map[dex.Network]string)
    29  	for net, netToken := range token.NetTokens {
    30  		netAddrs[net] = netToken.Address.String()
    31  	}
    32  	asset.RegisterToken(tokenID, token.Token, &asset.WalletDefinition{
    33  		Type:        walletTypeToken,
    34  		Tab:         "Polygon token",
    35  		Description: desc,
    36  	}, netAddrs)
    37  }
    38  
    39  func init() {
    40  	asset.Register(BipID, &Driver{})
    41  	registerToken(usdcTokenID, "The USDC Ethereum ERC20 token.", dex.Mainnet, dex.Testnet, dex.Simnet)
    42  	registerToken(usdtTokenID, "The USDT Ethereum ERC20 token.", dex.Mainnet, dex.Testnet, dex.Simnet)
    43  	registerToken(wbtcTokenID, "Wrapped BTC.", dex.Mainnet)
    44  	registerToken(wethTokenID, "Wrapped ETH.", dex.Mainnet)
    45  }
    46  
    47  const (
    48  	// BipID is the BIP-0044 asset ID for Polygon.
    49  	BipID              = 966
    50  	defaultGasFeeLimit = 1000
    51  	walletTypeRPC      = "rpc"
    52  	walletTypeToken    = "token"
    53  )
    54  
    55  var (
    56  	usdcTokenID, _ = dex.BipSymbolID("usdc.polygon")
    57  	usdtTokenID, _ = dex.BipSymbolID("usdt.polygon")
    58  	wethTokenID, _ = dex.BipSymbolID("weth.polygon")
    59  	wbtcTokenID, _ = dex.BipSymbolID("wbtc.polygon")
    60  	// WalletInfo defines some general information about a Polygon Wallet(EVM
    61  	// Compatible).
    62  
    63  	walletOpts = []*asset.ConfigOption{
    64  		{
    65  			Key:         "gasfeelimit",
    66  			DisplayName: "Gas Fee Limit",
    67  			Description: "This is the highest network fee rate you are willing to " +
    68  				"pay on swap transactions. If gasfeelimit is lower than a market's " +
    69  				"maxfeerate, you will not be able to trade on that market with this " +
    70  				"wallet.  Units: gwei / gas",
    71  			DefaultValue: strconv.FormatUint(defaultGasFeeLimit, 10),
    72  		},
    73  	}
    74  	WalletInfo = asset.WalletInfo{
    75  		Name:              "Polygon",
    76  		SupportedVersions: []uint32{0},
    77  		UnitInfo:          dexpolygon.UnitInfo,
    78  		AvailableWallets: []*asset.WalletDefinition{
    79  			{
    80  				Type:        walletTypeRPC,
    81  				Tab:         "External",
    82  				Description: "Infrastructure providers (e.g. Infura) or local nodes",
    83  				ConfigOpts:  append(eth.RPCOpts, walletOpts...),
    84  				Seeded:      true,
    85  				NoAuth:      true,
    86  			},
    87  			// MaxSwapsInTx and MaxRedeemsInTx are set in (Wallet).Info, since
    88  			// the value cannot be known until we connect and get network info.
    89  		},
    90  		IsAccountBased: true,
    91  	}
    92  )
    93  
    94  type Driver struct{}
    95  
    96  // Open opens the Polygon exchange wallet. Start the wallet with its Run method.
    97  func (d *Driver) Open(cfg *asset.WalletConfig, logger dex.Logger, net dex.Network) (asset.Wallet, error) {
    98  	chainCfg, err := ChainConfig(net)
    99  	if err != nil {
   100  		return nil, fmt.Errorf("failed to locate Polygon genesis configuration for network %s", net)
   101  	}
   102  	compat, err := NetworkCompatibilityData(net)
   103  	if err != nil {
   104  		return nil, fmt.Errorf("failed to locate Polygon compatibility data: %s", net)
   105  	}
   106  	contracts := make(map[uint32]common.Address, 1)
   107  	for ver, netAddrs := range dexpolygon.ContractAddresses {
   108  		for netw, addr := range netAddrs {
   109  			if netw == net {
   110  				contracts[ver] = addr
   111  				break
   112  			}
   113  		}
   114  	}
   115  
   116  	var defaultProviders []string
   117  	switch net {
   118  	case dex.Simnet:
   119  		u, _ := user.Current()
   120  		defaultProviders = []string{filepath.Join(u.HomeDir, "dextest", "polygon", "alpha", "bor", "bor.ipc")}
   121  	case dex.Testnet:
   122  		defaultProviders = []string{
   123  			"https://rpc-amoy.polygon.technology",
   124  			"wss://polygon-amoy-bor-rpc.publicnode.com",
   125  			"https://polygon-amoy.blockpi.network/v1/rpc/public",
   126  			"https://polygon-amoy.drpc.org",
   127  		}
   128  	case dex.Mainnet:
   129  		defaultProviders = []string{
   130  			"https://1rpc.io/matic",
   131  			"https://rpc.ankr.com/polygon",
   132  			"https://polygon.drpc.org",
   133  			"https://polygon.blockpi.network/v1/rpc/public",
   134  			"https://polygon.llamarpc.com",
   135  			"https://endpoints.omniatech.io/v1/matic/mainnet/public",
   136  			"https://rpc-mainnet.matic.quiknode.pro",
   137  			"https://gateway.tenderly.co/public/polygon",
   138  		}
   139  	}
   140  
   141  	// BipID, chainCfg, cfg, &t, dexpolygon.VersionedGases, dexpolygon.Tokens, logger, net
   142  	return eth.NewEVMWallet(&eth.EVMWalletConfig{
   143  		BaseChainID:        BipID,
   144  		ChainCfg:           chainCfg,
   145  		AssetCfg:           cfg,
   146  		CompatData:         &compat,
   147  		VersionedGases:     dexpolygon.VersionedGases,
   148  		Tokens:             dexpolygon.Tokens,
   149  		FinalizeConfs:      64,
   150  		Logger:             logger,
   151  		BaseChainContracts: contracts,
   152  		MultiBalAddress:    dexpolygon.MultiBalanceAddresses[net],
   153  		WalletInfo:         WalletInfo,
   154  		Net:                net,
   155  		DefaultProviders:   defaultProviders,
   156  	})
   157  }
   158  
   159  func (d *Driver) DecodeCoinID(coinID []byte) (string, error) {
   160  	return (&eth.Driver{}).DecodeCoinID(coinID)
   161  }
   162  
   163  func (d *Driver) Info() *asset.WalletInfo {
   164  	wi := WalletInfo
   165  	return &wi
   166  }
   167  
   168  func (d *Driver) Exists(walletType, dataDir string, settings map[string]string, net dex.Network) (bool, error) {
   169  	if walletType != walletTypeRPC {
   170  		return false, fmt.Errorf("unknown wallet type %q", walletType)
   171  	}
   172  	return (&eth.Driver{}).Exists(walletType, dataDir, settings, net)
   173  }
   174  
   175  func (d *Driver) Create(cfg *asset.CreateWalletParams) error {
   176  	compat, err := NetworkCompatibilityData(cfg.Net)
   177  	if err != nil {
   178  		return fmt.Errorf("error finding compatibility data: %v", err)
   179  	}
   180  	return eth.CreateEVMWallet(dexpolygon.ChainIDs[cfg.Net], cfg, &compat, false)
   181  }