diff --git a/package.json b/package.json index 2a3661292..d4cbdbb9f 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ "packages/extension", "packages/storage", "packages/request", - "packages/hw-wallets" + "packages/hw-wallets", + "packages/name-resolution" ], "scripts": { "test": "yarn workspaces foreach -pv run test", diff --git a/packages/extension/package.json b/packages/extension/package.json index cf8b96a3c..c672bf844 100644 --- a/packages/extension/package.json +++ b/packages/extension/package.json @@ -1,6 +1,6 @@ { "name": "@enkryptcom/extension", - "version": "1.6.0", + "version": "1.7.0", "private": true, "scripts": { "zip": "cd dist; zip -r release.zip *;", diff --git a/packages/extension/src/libs/dapp-list/index.ts b/packages/extension/src/libs/dapp-list/index.ts index 5cf861246..c45a3650e 100644 --- a/packages/extension/src/libs/dapp-list/index.ts +++ b/packages/extension/src/libs/dapp-list/index.ts @@ -2,35 +2,43 @@ import { NetworkNames } from "@enkryptcom/types"; const lists: Partial> = { [NetworkNames.Ethereum]: - "https://github.com/enkryptcom/dynamic-data/raw/main/dapps/eth.json", + "https://raw.githubusercontent.com/enkryptcom/dynamic-data/main/dapps/eth.json", [NetworkNames.Binance]: - "https://github.com/enkryptcom/dynamic-data/raw/main/dapps/bsc.json", + "https://raw.githubusercontent.com/enkryptcom/dynamic-data/main/dapps/bsc.json", [NetworkNames.Matic]: - "https://github.com/enkryptcom/dynamic-data/raw/main/dapps/matic.json", + "https://raw.githubusercontent.com/enkryptcom/dynamic-data/main/dapps/matic.json", [NetworkNames.EthereumClassic]: - "https://github.com/enkryptcom/dynamic-data/raw/main/dapps/etc.json", + "https://raw.githubusercontent.com/enkryptcom/dynamic-data/main/dapps/etc.json", [NetworkNames.Kusama]: - "https://github.com/enkryptcom/dynamic-data/raw/main/dapps/ksm.json", + "https://raw.githubusercontent.com/enkryptcom/dynamic-data/main/dapps/ksm.json", [NetworkNames.Polkadot]: - "https://github.com/enkryptcom/dynamic-data/raw/main/dapps/dot.json", + "https://raw.githubusercontent.com/enkryptcom/dynamic-data/main/dapps/dot.json", [NetworkNames.Acala]: "https://raw.githubusercontent.com/enkryptcom/dynamic-data/main/dapps/aca.json", [NetworkNames.Karura]: - "https://github.com/enkryptcom/dynamic-data/raw/main/dapps/kar.json", + "https://raw.githubusercontent.com/enkryptcom/dynamic-data/main/dapps/kar.json", [NetworkNames.Moonbeam]: - "https://github.com/enkryptcom/dynamic-data/raw/main/dapps/glmr.json", + "https://raw.githubusercontent.com/enkryptcom/dynamic-data/main/dapps/glmr.json", [NetworkNames.Moonriver]: - "https://github.com/enkryptcom/dynamic-data/raw/main/dapps/movr.json", + "https://raw.githubusercontent.com/enkryptcom/dynamic-data/main/dapps/movr.json", [NetworkNames.Astar]: - "https://github.com/enkryptcom/dynamic-data/raw/main/dapps/astr.json", + "https://raw.githubusercontent.com/enkryptcom/dynamic-data/main/dapps/astr.json", [NetworkNames.AstarEVM]: - "https://github.com/enkryptcom/dynamic-data/raw/main/dapps/astr.json", + "https://raw.githubusercontent.com/enkryptcom/dynamic-data/main/dapps/astr.json", [NetworkNames.Shiden]: - "https://github.com/enkryptcom/dynamic-data/raw/main/dapps/sdn.json", + "https://raw.githubusercontent.com/enkryptcom/dynamic-data/main/dapps/sdn.json", [NetworkNames.ShidenEVM]: - "https://github.com/enkryptcom/dynamic-data/raw/main/dapps/sdn.json", + "https://raw.githubusercontent.com/enkryptcom/dynamic-data/main/dapps/sdn.json", [NetworkNames.Okc]: - "https://github.com/enkryptcom/dynamic-data/raw/main/dapps/okc.json", + "https://raw.githubusercontent.com/enkryptcom/dynamic-data/main/dapps/okc.json", + [NetworkNames.Optimism]: + "https://raw.githubusercontent.com/enkryptcom/dynamic-data/main/dapps/op.json", + [NetworkNames.Canto]: + "https://raw.githubusercontent.com/enkryptcom/dynamic-data/main/dapps/canto.json", + [NetworkNames.Bifrost]: + "https://raw.githubusercontent.com/enkryptcom/dynamic-data/main/dapps/bifrost.json", + [NetworkNames.BifrostKusama]: + "https://raw.githubusercontent.com/enkryptcom/dynamic-data/main/dapps/bifrost.json", }; export default lists; diff --git a/packages/extension/src/libs/name-resolver/index.ts b/packages/extension/src/libs/name-resolver/index.ts new file mode 100644 index 000000000..0fb2f7f91 --- /dev/null +++ b/packages/extension/src/libs/name-resolver/index.ts @@ -0,0 +1,23 @@ +import NameResolver, { CoinType } from "@enkryptcom/name-resolution"; +class GenericNameResolver { + nameResolver: NameResolver; + + constructor() { + this.nameResolver = new NameResolver({ + ens: { node: "https://nodes.mewapi.io/rpc/eth" }, + }); + } + + async resolveName(name: string, coins: CoinType[]): Promise { + let response: string | null = null; + for (const coin of coins) { + response = await this.nameResolver + .resolveAddress(name, coin) + .catch(() => null); + if (response) return response; + } + return response; + } +} + +export { CoinType, GenericNameResolver }; diff --git a/packages/extension/src/manifest/base.json b/packages/extension/src/manifest/base.json index 4f6e2c8d8..096ecd316 100644 --- a/packages/extension/src/manifest/base.json +++ b/packages/extension/src/manifest/base.json @@ -2,7 +2,7 @@ "author": "https://www.enkrypt.com", "homepage_url": "https://www.enkrypt.com", "version": "", - "name": "Enkrypt: Ethereum, Polkadot and OKX Wallet", + "name": "Enkrypt: Ethereum, Polkadot and Canto Wallet", "short_name": "Enkrypt", "permissions": [ "storage", diff --git a/packages/extension/src/providers/ethereum/index.ts b/packages/extension/src/providers/ethereum/index.ts index 2fb2d6536..5baaab7e6 100644 --- a/packages/extension/src/providers/ethereum/index.ts +++ b/packages/extension/src/providers/ethereum/index.ts @@ -43,8 +43,13 @@ class EthereumProvider this.middlewares = Middlewares.map((mw) => mw.bind(this)); } setRequestProvider(network: BaseNetwork): void { + const prevURL = new URL(this.network.node); + const newURL = new URL(network.node); this.network = network as EvmNetwork; - this.requestProvider.changeNetwork(network.node); + if (prevURL.protocol === newURL.protocol) + this.requestProvider.changeNetwork(network.node); + else + this.requestProvider = getRequestProvider(network.node, this.middlewares); } async isPersistentEvent(request: ProviderRPCRequest): Promise { if (request.method === "eth_subscribe") return true; diff --git a/packages/extension/src/providers/ethereum/libs/activity-handlers/providers/etherscan/configs.ts b/packages/extension/src/providers/ethereum/libs/activity-handlers/providers/etherscan/configs.ts index 73ed83c02..e92de0a0b 100644 --- a/packages/extension/src/providers/ethereum/libs/activity-handlers/providers/etherscan/configs.ts +++ b/packages/extension/src/providers/ethereum/libs/activity-handlers/providers/etherscan/configs.ts @@ -13,6 +13,8 @@ const NetworkEndpoints = { [NetworkNames.KaruraEVM]: "https://blockscout.karura.network/", [NetworkNames.AstarEVM]: "https://blockscout.com/astar/", [NetworkNames.ShidenEVM]: "https://blockscout.com/shiden/", + [NetworkNames.Optimism]: "https://api-optimistic.etherscan.io/", + [NetworkNames.Canto]: "https://evm.explorer.canto.io/", }; export { NetworkEndpoints }; diff --git a/packages/extension/src/providers/ethereum/libs/assets-handlers/types/tokenbalance-mew.ts b/packages/extension/src/providers/ethereum/libs/assets-handlers/types/tokenbalance-mew.ts index 89b766bdb..0d712e8ba 100644 --- a/packages/extension/src/providers/ethereum/libs/assets-handlers/types/tokenbalance-mew.ts +++ b/packages/extension/src/providers/ethereum/libs/assets-handlers/types/tokenbalance-mew.ts @@ -10,7 +10,7 @@ export interface SupportedNetwork { cgPlatform: string; } export interface CGToken { - chainId: number; + chainId: `0x${string}`; address: string; name: string; symbol: string; diff --git a/packages/extension/src/providers/ethereum/libs/tx-broadcaster.ts b/packages/extension/src/providers/ethereum/libs/tx-broadcaster.ts new file mode 100644 index 000000000..d9fdc8a9e --- /dev/null +++ b/packages/extension/src/providers/ethereum/libs/tx-broadcaster.ts @@ -0,0 +1,28 @@ +import { NetworkNames } from "@enkryptcom/types"; +import { v4 } from "uuid"; + +const broadcastTx = (hexTx: string, network: NetworkNames): Promise => { + if (network === NetworkNames.Ethereum) { + const burl = "https://broadcast.mewapi.io/eth?product=enkrypt"; + return fetch(burl, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + jsonrpc: "2.0", + method: "eth_sendRawTransaction", + params: [hexTx], + id: v4(), + }), + }) + .then((response) => response.json()) + .then((jRes) => { + if (jRes.error) return Promise.reject(jRes.error); + else return jRes.result as string; + }); + } + return Promise.reject("Not valid network"); +}; + +export default broadcastTx; diff --git a/packages/extension/src/providers/ethereum/methods/eth_sendRawTransaction.ts b/packages/extension/src/providers/ethereum/methods/eth_sendRawTransaction.ts new file mode 100644 index 000000000..433b0bfbc --- /dev/null +++ b/packages/extension/src/providers/ethereum/methods/eth_sendRawTransaction.ts @@ -0,0 +1,25 @@ +import { getCustomError } from "@/libs/error"; +import { MiddlewareFunction } from "@enkryptcom/types"; +import EthereumProvider from ".."; +import broadcastTx from "../libs/tx-broadcaster"; +const method: MiddlewareFunction = function ( + this: EthereumProvider, + payload, + res, + next +): void { + if (payload.method !== "eth_sendRawTransaction") return next(); + else { + if (!payload.params || payload.params.length < 1) { + return res( + getCustomError("eth_sendTransaction: invalid request not enough params") + ); + } + broadcastTx(payload.params[0], this.network.name) + .then((hash) => { + res(null, hash); + }) + .catch(() => next()); + } +}; +export default method; diff --git a/packages/extension/src/providers/ethereum/methods/index.ts b/packages/extension/src/providers/ethereum/methods/index.ts index af8dc5e3b..918debe54 100644 --- a/packages/extension/src/providers/ethereum/methods/index.ts +++ b/packages/extension/src/providers/ethereum/methods/index.ts @@ -11,6 +11,7 @@ import addEthereumChain from "./wallet_addEthereumChain"; import switchEthereumChain from "./wallet_switchEthereumChain"; import watchAsset from "./wallet_watchAsset"; import walletRequestPermissions from "./wallet_requestPermissions"; +import ethSendRawTransaction from "./eth_sendRawTransaction"; export default [ ethSendTransaction, ethSign, @@ -25,4 +26,5 @@ export default [ switchEthereumChain, addEthereumChain, walletRequestPermissions, + ethSendRawTransaction, ]; diff --git a/packages/extension/src/providers/ethereum/methods/wallet_addEthereumChain.ts b/packages/extension/src/providers/ethereum/methods/wallet_addEthereumChain.ts index 0132d4c42..0c00ffa1e 100644 --- a/packages/extension/src/providers/ethereum/methods/wallet_addEthereumChain.ts +++ b/packages/extension/src/providers/ethereum/methods/wallet_addEthereumChain.ts @@ -2,7 +2,6 @@ import { getCustomError } from "@/libs/error"; import { MiddlewareFunction } from "@enkryptcom/types"; import EthNetworks from "../networks"; import EthereumProvider from ".."; -import { numberToHex } from "web3-utils"; import { sendToBackgroundFromBackground } from "@/libs/messenger/extension"; import { InternalMethods } from "@/types/messenger"; import { ProviderRPCRequest } from "@/types/provider"; @@ -26,7 +25,7 @@ const method: MiddlewareFunction = function ( } const allNetworks = Object.values(EthNetworks); const validNetwork = allNetworks.find( - (net) => numberToHex(net.chainID) === payload.params![0].chainId + (net) => net.chainID === payload.params![0].chainId ); if (validNetwork) { sendToBackgroundFromBackground({ diff --git a/packages/extension/src/providers/ethereum/methods/wallet_switchEthereumChain.ts b/packages/extension/src/providers/ethereum/methods/wallet_switchEthereumChain.ts index 84f767538..f91d4b8be 100644 --- a/packages/extension/src/providers/ethereum/methods/wallet_switchEthereumChain.ts +++ b/packages/extension/src/providers/ethereum/methods/wallet_switchEthereumChain.ts @@ -5,7 +5,6 @@ import { ProviderRPCRequest } from "@/types/provider"; import { MiddlewareFunction } from "@enkryptcom/types"; import EthNetworks from "../networks"; import EthereumProvider from ".."; -import { numberToHex } from "web3-utils"; import { MessageMethod } from "../types"; import DomainState from "@/libs/domain-state"; const method: MiddlewareFunction = function ( @@ -25,7 +24,7 @@ const method: MiddlewareFunction = function ( } const allNetworks = Object.values(EthNetworks); const validNetwork = allNetworks.find( - (net) => numberToHex(net.chainID) === payload.params![0].chainId + (net) => net.chainID === payload.params![0].chainId ); if (validNetwork) { sendToBackgroundFromBackground({ diff --git a/packages/extension/src/providers/ethereum/networks/astr.ts b/packages/extension/src/providers/ethereum/networks/astr.ts index 8af5a4adf..2478a618d 100644 --- a/packages/extension/src/providers/ethereum/networks/astr.ts +++ b/packages/extension/src/providers/ethereum/networks/astr.ts @@ -9,9 +9,10 @@ const astrOptions: EvmNetworkOptions = { homePage: "https://astar.network/", blockExplorerTX: "https://blockscout.com/astar/tx/[[txHash]]", blockExplorerAddr: "https://blockscout.com/astar/address/[[address]]", - chainID: 592, + chainID: "0x250", isTestNetwork: false, currencyName: "ASTR", + currencyNameLong: "Astar", node: "wss://astar.public.blastapi.io/", icon: require("./icons/astr.png"), gradient: "linear-gradient(180deg, #C549FF 0%, #684CFF 100%)", diff --git a/packages/extension/src/providers/ethereum/networks/bsc.ts b/packages/extension/src/providers/ethereum/networks/bsc.ts index 55fa73722..709be7266 100644 --- a/packages/extension/src/providers/ethereum/networks/bsc.ts +++ b/packages/extension/src/providers/ethereum/networks/bsc.ts @@ -10,9 +10,10 @@ const bscOptions: EvmNetworkOptions = { homePage: "https://www.binance.org/en/smartChain", blockExplorerTX: "https://bscscan.com/tx/[[txHash]]", blockExplorerAddr: "https://bscscan.com/address/[[address]]", - chainID: 56, + chainID: "0x38", isTestNetwork: false, currencyName: "BNB", + currencyNameLong: "Binance", node: "wss://nodes.mewapi.io/ws/bsc", icon: require("./icons/bsc.svg"), gradient: "#F0B90B", diff --git a/packages/extension/src/providers/ethereum/networks/canto.ts b/packages/extension/src/providers/ethereum/networks/canto.ts new file mode 100644 index 000000000..da6ef2a59 --- /dev/null +++ b/packages/extension/src/providers/ethereum/networks/canto.ts @@ -0,0 +1,26 @@ +import wrapActivityHandler from "@/libs/activity-state/wrap-activity-handler"; +import { CoingeckoPlatform, NetworkNames } from "@enkryptcom/types"; +import { EtherscanActivity } from "../libs/activity-handlers"; +import { EvmNetwork, EvmNetworkOptions } from "../types/evm-network"; + +const cantoOptions: EvmNetworkOptions = { + name: NetworkNames.Canto, + name_long: "Canto", + homePage: "https://canto.io/", + blockExplorerTX: "https://evm.explorer.canto.io/tx/[[txHash]]", + blockExplorerAddr: "https://evm.explorer.canto.io/address/[[address]]", + chainID: "0x1e14", + isTestNetwork: false, + currencyName: "CANTO", + currencyNameLong: "Canto", + node: "https://canto.evm.chandrastation.com/", + icon: require("./icons/canto.svg"), + gradient: "linear-gradient(180deg, #C549FF 0%, #684CFF 100%)", + coingeckoID: "canto", + coingeckoPlatform: CoingeckoPlatform.Canto, + activityHandler: wrapActivityHandler(EtherscanActivity), +}; + +const canto = new EvmNetwork(cantoOptions); + +export default canto; diff --git a/packages/extension/src/providers/ethereum/networks/etc.ts b/packages/extension/src/providers/ethereum/networks/etc.ts index cad57b327..e060efe37 100644 --- a/packages/extension/src/providers/ethereum/networks/etc.ts +++ b/packages/extension/src/providers/ethereum/networks/etc.ts @@ -9,9 +9,10 @@ const etcOptions: EvmNetworkOptions = { homePage: "https://ethereumclassic.org/", blockExplorerTX: "https://blockscout.com/etc/mainnet/tx/[[txHash]]", blockExplorerAddr: "https://blockscout.com/etc/mainnet/address/[[address]]", - chainID: 61, + chainID: "0x3d", isTestNetwork: false, currencyName: "ETC", + currencyNameLong: "Ethereum Classic", node: "wss://nodes.mewapi.io/ws/etc", icon: require("./icons/etc.svg"), gradient: "linear-gradient(180deg, #C549FF 0%, #684CFF 100%)", diff --git a/packages/extension/src/providers/ethereum/networks/eth.ts b/packages/extension/src/providers/ethereum/networks/eth.ts index ddececb67..29f8821bb 100644 --- a/packages/extension/src/providers/ethereum/networks/eth.ts +++ b/packages/extension/src/providers/ethereum/networks/eth.ts @@ -11,9 +11,10 @@ const ethOptions: EvmNetworkOptions = { homePage: "https://ethereum.org", blockExplorerTX: "https://www.ethvm.com/tx/[[txHash]]", blockExplorerAddr: "https://www.ethvm.com/address/[[address]]", - chainID: 1, + chainID: "0x1", isTestNetwork: false, currencyName: "ETH", + currencyNameLong: "Ethereum", node: "wss://nodes.mewapi.io/ws/eth", icon: require("./icons/eth.svg"), gradient: "linear-gradient(180deg, #C549FF 0%, #684CFF 100%)", diff --git a/packages/extension/src/providers/ethereum/networks/goerli.ts b/packages/extension/src/providers/ethereum/networks/goerli.ts index 7aa0d429a..b66ca0da0 100644 --- a/packages/extension/src/providers/ethereum/networks/goerli.ts +++ b/packages/extension/src/providers/ethereum/networks/goerli.ts @@ -9,9 +9,10 @@ const goerliOptions: EvmNetworkOptions = { homePage: "https://github.com/goerli/testnet", blockExplorerTX: "https://goerli.etherscan.io/tx/[[txHash]]", blockExplorerAddr: "https://goerli.etherscan.io/address/[[address]]", - chainID: 5, + chainID: "0x5", isTestNetwork: true, currencyName: "GöETH", + currencyNameLong: "Goerli", node: "wss://nodes.mewapi.io/ws/goerli", icon: require("./icons/eth.svg"), gradient: "linear-gradient(180deg, #C549FF 0%, #684CFF 100%)", diff --git a/packages/extension/src/providers/ethereum/networks/icons/canto.svg b/packages/extension/src/providers/ethereum/networks/icons/canto.svg new file mode 100644 index 000000000..029028234 --- /dev/null +++ b/packages/extension/src/providers/ethereum/networks/icons/canto.svg @@ -0,0 +1,4 @@ + + + + diff --git a/packages/extension/src/providers/ethereum/networks/icons/op.svg b/packages/extension/src/providers/ethereum/networks/icons/op.svg new file mode 100644 index 000000000..336c6f8c0 --- /dev/null +++ b/packages/extension/src/providers/ethereum/networks/icons/op.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/packages/extension/src/providers/ethereum/networks/index.ts b/packages/extension/src/providers/ethereum/networks/index.ts index 425665a44..d538760ce 100644 --- a/packages/extension/src/providers/ethereum/networks/index.ts +++ b/packages/extension/src/providers/ethereum/networks/index.ts @@ -12,6 +12,8 @@ import karuraEvmNode from "./karura"; import okcNode from "./okc"; import shidenEvmNode from "./sdn"; import astarEvmNode from "./astr"; +import optimismNode from "./op"; +import cantoNode from "./canto"; export default { goerli: goerliNode, @@ -28,4 +30,6 @@ export default { okc: okcNode, shidenEvm: shidenEvmNode, astarEvm: astarEvmNode, + op: optimismNode, + canto: cantoNode, }; diff --git a/packages/extension/src/providers/ethereum/networks/karura.ts b/packages/extension/src/providers/ethereum/networks/karura.ts index ffd305aa4..b8d334971 100644 --- a/packages/extension/src/providers/ethereum/networks/karura.ts +++ b/packages/extension/src/providers/ethereum/networks/karura.ts @@ -9,9 +9,10 @@ const karuraOptions: EvmNetworkOptions = { homePage: "https://karura.network", blockExplorerTX: "https://blockscout.karura.network/tx/[[txHash]]", blockExplorerAddr: "https://blockscout.karura.network/address/[[address]]", - chainID: 686, + chainID: "0x2ae", isTestNetwork: false, currencyName: "KAR", + currencyNameLong: "Karura", node: "wss://eth-rpc-karura.aca-api.network/ws", icon: require("./icons/karura-evm.svg"), gradient: "linear-gradient(330.21deg, #E40C5B -26.31%, #FF4C3B 88.17%)", diff --git a/packages/extension/src/providers/ethereum/networks/kov.ts b/packages/extension/src/providers/ethereum/networks/kov.ts index 4fbbd0af5..3d123379c 100644 --- a/packages/extension/src/providers/ethereum/networks/kov.ts +++ b/packages/extension/src/providers/ethereum/networks/kov.ts @@ -9,9 +9,10 @@ const kovOptions: EvmNetworkOptions = { homePage: "https://github.com/kovan-testnet", blockExplorerTX: "https://kovan.etherscan.io/tx/[[txHash]]", blockExplorerAddr: "https://kovan.etherscan.io/address/[[address]]", - chainID: 42, + chainID: "0x2a", isTestNetwork: true, currencyName: "KOV", + currencyNameLong: "Kovan", node: "wss://nodes.mewapi.io/ws/kovan", icon: require("./icons/eth.svg"), gradient: "linear-gradient(180deg, #C549FF 0%, #684CFF 100%)", diff --git a/packages/extension/src/providers/ethereum/networks/matic.ts b/packages/extension/src/providers/ethereum/networks/matic.ts index ad6a6b15b..b5b9e8858 100644 --- a/packages/extension/src/providers/ethereum/networks/matic.ts +++ b/packages/extension/src/providers/ethereum/networks/matic.ts @@ -11,9 +11,10 @@ const maticOptions: EvmNetworkOptions = { homePage: "https://polygonscan.com/", blockExplorerTX: "https://polygonscan.com/tx/[[txHash]]", blockExplorerAddr: "https://polygonscan.com/address/[[address]]", - chainID: 137, + chainID: "0x89", isTestNetwork: false, currencyName: "MATIC", + currencyNameLong: "Polygon Matic", node: "wss://nodes.mewapi.io/ws/matic", icon: require("./icons/matic.svg"), gradient: "#7B3FE4", diff --git a/packages/extension/src/providers/ethereum/networks/moonbeam/index.ts b/packages/extension/src/providers/ethereum/networks/moonbeam/index.ts index 1816c0035..355e37f8b 100644 --- a/packages/extension/src/providers/ethereum/networks/moonbeam/index.ts +++ b/packages/extension/src/providers/ethereum/networks/moonbeam/index.ts @@ -10,9 +10,10 @@ const moonbeamOptions: EvmNetworkOptions = { homePage: "https://moonbeam.network", blockExplorerTX: "https://moonscan.io/tx/[[txHash]]", blockExplorerAddr: "https://moonscan.io/address/[[address]]", - chainID: 1284, + chainID: "0x504", isTestNetwork: false, currencyName: "GLMR", + currencyNameLong: "Moonbeam", node: "wss://wss.api.moonbeam.network/", icon: require("../icons/moonbeam.svg"), gradient: "#53CBC9", diff --git a/packages/extension/src/providers/ethereum/networks/moonriver/index.ts b/packages/extension/src/providers/ethereum/networks/moonriver/index.ts index 10e62de9d..13c2d8275 100644 --- a/packages/extension/src/providers/ethereum/networks/moonriver/index.ts +++ b/packages/extension/src/providers/ethereum/networks/moonriver/index.ts @@ -10,9 +10,10 @@ const moonriverOptions: EvmNetworkOptions = { homePage: "https://moonbeam.network/networks/moonriver/", blockExplorerTX: "https://moonriver.moonscan.io//tx/[[txHash]]", blockExplorerAddr: "https://moonriver.moonscan.io/address/[[address]]", - chainID: 1285, + chainID: "0x505", isTestNetwork: false, currencyName: "MOVR", + currencyNameLong: "Moonriver", node: "wss://wss.api.moonriver.moonbeam.network", icon: require("../icons/moonriver.svg"), gradient: "linear-gradient(180deg, #F2B705 0%, #53CBC8 100%)", diff --git a/packages/extension/src/providers/ethereum/networks/okc.ts b/packages/extension/src/providers/ethereum/networks/okc.ts index c2b99bcdf..211fc90f2 100644 --- a/packages/extension/src/providers/ethereum/networks/okc.ts +++ b/packages/extension/src/providers/ethereum/networks/okc.ts @@ -9,9 +9,10 @@ const okcOptions: EvmNetworkOptions = { homePage: "https://www.oklink.com/en/okc", blockExplorerTX: "https://www.oklink.com/en/okc/tx/[[txHash]]", blockExplorerAddr: "https://www.oklink.com/en/okc/address/[[address]]", - chainID: 66, + chainID: "0x42", isTestNetwork: false, currencyName: "OKT", + currencyNameLong: "OKX Chain", node: "https://exchainrpc.okex.org", icon: require("./icons/okc.svg"), gradient: "linear-gradient(180deg, #C549FF 0%, #684CFF 100%)", diff --git a/packages/extension/src/providers/ethereum/networks/op.ts b/packages/extension/src/providers/ethereum/networks/op.ts new file mode 100644 index 000000000..7e6efed09 --- /dev/null +++ b/packages/extension/src/providers/ethereum/networks/op.ts @@ -0,0 +1,26 @@ +import { CoingeckoPlatform, NetworkNames } from "@enkryptcom/types"; +import { EvmNetwork, EvmNetworkOptions } from "../types/evm-network"; +import { EtherscanActivity } from "../libs/activity-handlers"; +import wrapActivityHandler from "@/libs/activity-state/wrap-activity-handler"; + +const opOptions: EvmNetworkOptions = { + name: NetworkNames.Optimism, + name_long: "Optimism", + homePage: "https://www.optimism.io/", + blockExplorerTX: "https://optimistic.etherscan.io/tx/[[txHash]]", + blockExplorerAddr: "https://optimistic.etherscan.io/address/[[address]]", + chainID: "0xa", + isTestNetwork: false, + currencyName: "ETH", + currencyNameLong: "Ethereum", + node: "https://mainnet.optimism.io", + icon: require("./icons/op.svg"), + gradient: "linear-gradient(180deg, #C549FF 0%, #684CFF 100%)", + coingeckoID: "ethereum", + coingeckoPlatform: CoingeckoPlatform.Optimism, + activityHandler: wrapActivityHandler(EtherscanActivity), +}; + +const op = new EvmNetwork(opOptions); + +export default op; diff --git a/packages/extension/src/providers/ethereum/networks/rin.ts b/packages/extension/src/providers/ethereum/networks/rin.ts index 43cbdf689..47a96dcf8 100644 --- a/packages/extension/src/providers/ethereum/networks/rin.ts +++ b/packages/extension/src/providers/ethereum/networks/rin.ts @@ -9,9 +9,10 @@ const rinOptions: EvmNetworkOptions = { homePage: "https://www.rinkeby.io/", blockExplorerTX: "https://rinkeby.etherscan.io/tx/[[txHash]]", blockExplorerAddr: "https://rinkeby.etherscan.io/address/[[address]]", - chainID: 4, + chainID: "0x4", isTestNetwork: true, currencyName: "RIN", + currencyNameLong: "Rinkeby", node: "wss://nodes.mewapi.io/ws/rinkeby", icon: require("./icons/eth.svg"), gradient: "linear-gradient(180deg, #C549FF 0%, #684CFF 100%)", diff --git a/packages/extension/src/providers/ethereum/networks/rop.ts b/packages/extension/src/providers/ethereum/networks/rop.ts index 1773a7fd6..bd64a3e4c 100644 --- a/packages/extension/src/providers/ethereum/networks/rop.ts +++ b/packages/extension/src/providers/ethereum/networks/rop.ts @@ -9,9 +9,10 @@ const ropOptions: EvmNetworkOptions = { homePage: "https://github.com/ethereum/ropsten", blockExplorerTX: "https://ropsten.etherscan.io/tx/[[txHash]]", blockExplorerAddr: "https://ropsten.etherscan.io/address/[[address]]", - chainID: 3, + chainID: "0x3", isTestNetwork: true, currencyName: "ROP", + currencyNameLong: "Ropsten", node: "wss://nodes.mewapi.io/ws/rop", icon: require("./icons/eth.svg"), basePath: "m/44'/1'/0'/0", diff --git a/packages/extension/src/providers/ethereum/networks/sdn.ts b/packages/extension/src/providers/ethereum/networks/sdn.ts index 250c613ae..b93445da9 100644 --- a/packages/extension/src/providers/ethereum/networks/sdn.ts +++ b/packages/extension/src/providers/ethereum/networks/sdn.ts @@ -9,9 +9,10 @@ const sdnOptions: EvmNetworkOptions = { homePage: "https://shiden.astar.network/", blockExplorerTX: "https://blockscout.com/shiden/tx/[[txHash]]", blockExplorerAddr: "https://blockscout.com/shiden/address/[[address]]", - chainID: 336, + chainID: "0x150", isTestNetwork: false, currencyName: "SDN", + currencyNameLong: "Shiden", node: "wss://shiden.public.blastapi.io", icon: require("./icons/sdn.png"), gradient: "linear-gradient(180deg, #C549FF 0%, #684CFF 100%)", diff --git a/packages/extension/src/providers/ethereum/types/evm-network.ts b/packages/extension/src/providers/ethereum/types/evm-network.ts index edbeb740c..169162943 100644 --- a/packages/extension/src/providers/ethereum/types/evm-network.ts +++ b/packages/extension/src/providers/ethereum/types/evm-network.ts @@ -26,9 +26,10 @@ export interface EvmNetworkOptions { homePage: string; blockExplorerTX: string; blockExplorerAddr: string; - chainID: number; + chainID: `0x${string}`; isTestNetwork: boolean; currencyName: string; + currencyNameLong: string; node: string; icon: string; gradient: string; @@ -51,7 +52,7 @@ export interface EvmNetworkOptions { } export class EvmNetwork extends BaseNetwork { - public chainID: number; + public chainID: `0x${string}`; private assetsInfoHandler?: ( network: BaseNetwork, @@ -131,8 +132,8 @@ export class EvmNetwork extends BaseNetwork { fromBase(balance, this.decimals) ).times(nativeMarketData?.current_price ?? 0); const nativeAsset: AssetsType = { - name: this.name_long, - symbol: this.name, + name: this.currencyNameLong, + symbol: this.currencyName, icon: this.icon, balance, balancef: formatFloatingPointValue(fromBase(balance, this.decimals)) @@ -208,10 +209,15 @@ export class EvmNetwork extends BaseNetwork { return true; }) as CustomErc20Token[]; - return erc20Tokens.map( - ({ name, symbol, address, icon, decimals }) => - new Erc20Token({ name, symbol, contract: address, icon, decimals }) - ); + return erc20Tokens.map(({ name, symbol, address, icon, decimals }) => { + return new Erc20Token({ + name, + symbol, + contract: address, + icon, + decimals, + }); + }); }); const balancePromises = customTokens.map((token) => @@ -238,7 +244,7 @@ export class EvmNetwork extends BaseNetwork { balanceUSDf: "0", value: "0", valuef: "0", - decimals: this.decimals, + decimals: token.decimals, sparkline: "", priceChangePercentage: 0, icon: token.icon, @@ -247,9 +253,9 @@ export class EvmNetwork extends BaseNetwork { const marketInfo = marketInfos[token.contract.toLowerCase()]; if (marketInfo) { - const usdBalance = new BigNumber(token.balance ?? "0").times( - marketInfo.current_price - ); + const usdBalance = new BigNumber( + fromBase(token.balance ?? "0", token.decimals) + ).times(marketInfo.current_price); asset.balanceUSD = usdBalance.toNumber(); asset.balanceUSDf = formatFiatValue(usdBalance.toString()).value; asset.value = marketInfo.current_price.toString(); diff --git a/packages/extension/src/providers/ethereum/types/index.ts b/packages/extension/src/providers/ethereum/types/index.ts index 119c520ed..0bf74229c 100644 --- a/packages/extension/src/providers/ethereum/types/index.ts +++ b/packages/extension/src/providers/ethereum/types/index.ts @@ -52,7 +52,7 @@ export interface EthereumRequest { export interface EthereumNodeType extends NodeType { signer: [SignerType.secp256k1]; - chainID: number; + chainID: `0x${string}`; } export interface ERC20TokenInfo { diff --git a/packages/extension/src/providers/ethereum/ui/eth-verify-transaction.vue b/packages/extension/src/providers/ethereum/ui/eth-verify-transaction.vue index ac0a780e8..c8477db68 100644 --- a/packages/extension/src/providers/ethereum/ui/eth-verify-transaction.vue +++ b/packages/extension/src/providers/ethereum/ui/eth-verify-transaction.vue @@ -157,6 +157,7 @@ import { Activity, ActivityStatus, ActivityType } from "@/types/activity"; import { generateAddress } from "ethereumjs-util"; import ActivityState from "@/libs/activity-state"; import { bigIntToBuffer } from "@enkryptcom/utils"; +import broadcastTx from "../libs/tx-broadcaster"; const isProcessing = ref(false); const isOpenSelectFee = ref(false); @@ -280,62 +281,66 @@ const approve = async () => { account: account.value, network: network.value, payload: finalizedTx, - }) - .then((tx) => { - const txActivity: Activity = { - from: account.value.address, - to: tx.to - ? tx.to.toString() - : `0x${generateAddress( - tx.getSenderAddress().toBuffer(), - bigIntToBuffer(tx.nonce) - ).toString("hex")}`, - isIncoming: tx.getSenderAddress().toString() === tx.to?.toString(), - network: network.value.name, - status: ActivityStatus.pending, - timestamp: new Date().getTime(), - token: { - decimals: decodedTx.value?.tokenDecimals || 18, - icon: decodedTx.value?.tokenImage || "", - name: decodedTx.value?.tokenName || "Unknown", - symbol: decodedTx.value?.tokenSymbol || "UKNWN", - price: decodedTx.value?.currentPriceUSD.toString() || "0", - }, - type: ActivityType.transaction, - value: decodedTx.value?.tokenValue || "0x0", - transactionHash: "", - }; - web3 - .sendSignedTransaction("0x" + tx.serialize().toString("hex")) - .on("transactionHash", (hash) => { - activityState - .addActivities( - [{ ...txActivity, ...{ transactionHash: hash } }], - { address: txActivity.from, network: network.value.name } - ) - .then(() => { - Resolve.value({ - result: JSON.stringify(hash), - }); - }); + }).then((tx) => { + const txActivity: Activity = { + from: account.value.address, + to: tx.to + ? tx.to.toString() + : `0x${generateAddress( + tx.getSenderAddress().toBuffer(), + bigIntToBuffer(tx.nonce) + ).toString("hex")}`, + isIncoming: tx.getSenderAddress().toString() === tx.to?.toString(), + network: network.value.name, + status: ActivityStatus.pending, + timestamp: new Date().getTime(), + token: { + decimals: decodedTx.value?.tokenDecimals || 18, + icon: decodedTx.value?.tokenImage || "", + name: decodedTx.value?.tokenName || "Unknown", + symbol: decodedTx.value?.tokenSymbol || "UKNWN", + price: decodedTx.value?.currentPriceUSD.toString() || "0", + }, + type: ActivityType.transaction, + value: decodedTx.value?.tokenValue || "0x0", + transactionHash: "", + }; + const onHash = (hash: string) => { + activityState + .addActivities([{ ...txActivity, ...{ transactionHash: hash } }], { + address: txActivity.from, + network: network.value.name, }) - .on("error", (error) => { - txActivity.status = ActivityStatus.failed; - activityState - .addActivities([txActivity], { - address: txActivity.from, - network: network.value.name, - }) - .then(() => { - Resolve.value({ - error: getCustomError(error.message), - }); - }); + .then(() => { + Resolve.value({ + result: JSON.stringify(hash), + }); }); - }) - .catch((err) => { - Resolve.value(err); - }); + }; + broadcastTx("0x" + tx.serialize().toString("hex"), network.value.name) + .then(onHash) + .catch(() => { + web3 + .sendSignedTransaction("0x" + tx.serialize().toString("hex")) + .on("transactionHash", onHash) + .on("error", (error) => { + txActivity.status = ActivityStatus.failed; + activityState + .addActivities([txActivity], { + address: txActivity.from, + network: network.value.name, + }) + .then(() => { + Resolve.value({ + error: getCustomError(error.message), + }); + }); + }); + }) + .catch((err) => { + Resolve.value(err); + }); + }); } ); }; diff --git a/packages/extension/src/providers/ethereum/ui/send-transaction/index.vue b/packages/extension/src/providers/ethereum/ui/send-transaction/index.vue index 7206bf585..7e2042764 100644 --- a/packages/extension/src/providers/ethereum/ui/send-transaction/index.vue +++ b/packages/extension/src/providers/ethereum/ui/send-transaction/index.vue @@ -129,6 +129,7 @@