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(ð.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 (ð.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 (ð.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 }