From 7107ffdc48ad1102688b29a6ae6b63c50c2aaea7 Mon Sep 17 00:00:00 2001 From: yhtiyar Date: Wed, 25 Aug 2021 17:04:58 +0300 Subject: [PATCH 01/19] adding address_info endpoint --- backend/moonstream/actions.py | 48 ++++++++++++++++++++++- backend/moonstream/data.py | 12 ++++++ backend/moonstream/routes/address_info.py | 10 +++++ backend/moonstream/routes/txinfo.py | 14 ++++++- 4 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 backend/moonstream/routes/address_info.py diff --git a/backend/moonstream/actions.py b/backend/moonstream/actions.py index 313bb64a..38c20398 100644 --- a/backend/moonstream/actions.py +++ b/backend/moonstream/actions.py @@ -3,7 +3,7 @@ import logging from typing import Dict, Any, List, Optional, Union - +from enum import Enum from sqlalchemy.engine.base import Transaction from moonstreamdb.models import ( EthereumBlock, @@ -265,6 +265,52 @@ def parse_search_query_to_sqlalchemy_filters(q: str, allowed_addresses: List[str return constructed_filters +class AdressType: + TOKEN = 0 + SMART_CONTRACT = 1 + NFT = 2 + EXCHANGE = 3 + + +class LabelNames(Enum): + ETHERSCAN_SMARTCONTRACT = "etherscan_smartcontract" + COINMARKETCAP_TOKEN = "coinmarketcap_token" + EXCHANGE = "EXCANGE" + + +def get_ethereum_address_info( + db_session: Session, address: str +) -> Optional[data.EthereumAddressInfo]: + query = db_session.query(EthereumAddress.id).filter( + EthereumAddress.address == address + ) + id = query.one_or_none() + if id is None: + return None + labels = ( + db_session.query(EthereumLabel).filter(EthereumLabel.address_id == id[0]).all() + ) + address_info = data.EthereumAddressInfo(address=address) + for label in labels: + if label.label == LabelNames.ETHERSCAN_SMARTCONTRACT: + address_info.address_type = AdressType.SMART_CONTRACT + address_info.details.name = label.label_data["name"] + address_info.details.external_URL = ( + f"https://etherscan.io/address/{address}" + ) + elif label.label == LabelNames.COINMARKETCAP_TOKEN: + address_info.address_type = AdressType.TOKEN + address_info.details.name = label.label_data["name"] + address_info.details.symbol = label.label_data["symbol"] + address_info.details.external_URL = label.label_data["coinmarketcap_url"] + elif label.label == LabelNames.EXCHANGE: + address_info.address_type = AdressType.EXCHANGE + address_info.details.name = label.label_data["name"] + address_info.details.symbol = label.label_data["label"] + + return address_info + + def get_contract_source_info( db_session: Session, contract_address: str ) -> Optional[data.EthereumSmartContractSourceInfo]: diff --git a/backend/moonstream/data.py b/backend/moonstream/data.py index 93b8ecb0..fbbd0a29 100644 --- a/backend/moonstream/data.py +++ b/backend/moonstream/data.py @@ -140,6 +140,18 @@ class EthereumSmartContractSourceInfo(BaseModel): compiler_version: str +class EthereumAddressDetails(BaseModel): + name: Optional[str] + symbol: Optional[str] + external_URL: Optional[str] + + +class EthereumAddressInfo(BaseModel): + address: str + address_type: Optional[int] + details: EthereumAddressDetails = EthereumAddressDetails() + + class TxinfoEthereumBlockchainResponse(BaseModel): tx: EthereumTransaction is_smart_contract_deployment: bool = False diff --git a/backend/moonstream/routes/address_info.py b/backend/moonstream/routes/address_info.py new file mode 100644 index 00000000..967e7521 --- /dev/null +++ b/backend/moonstream/routes/address_info.py @@ -0,0 +1,10 @@ +import logging +from typing import Dict, Optional + +from sqlalchemy.sql.expression import true + +from fastapi import FastAPI, Depends, HTTPException, Query +from fastapi.middleware.cors import CORSMiddleware +from moonstreamdb.db import yield_db_session +from moonstreamdb.models import EthereumAddress +from sqlalchemy.orm import Session diff --git a/backend/moonstream/routes/txinfo.py b/backend/moonstream/routes/txinfo.py index 18f4f320..ae523131 100644 --- a/backend/moonstream/routes/txinfo.py +++ b/backend/moonstream/routes/txinfo.py @@ -10,7 +10,7 @@ from typing import Dict, Optional from sqlalchemy.sql.expression import true -from fastapi import FastAPI, Depends, HTTPException, Query +from fastapi import FastAPI, Depends, HTTPException, Query, Form from fastapi.middleware.cors import CORSMiddleware from moonstreamdb.db import yield_db_session from moonstreamdb.models import EthereumAddress @@ -94,6 +94,18 @@ async def txinfo_ethereum_blockchain_handler( return response +@app.get( + "/ethereum_blockchain/address_info", + tags=["address info"], + response_model=data.EthereumAddressInfo, +) +async def address_info_handler( + address: str = Form(...), db_session: Session = Depends(yield_db_session) +) -> Optional[data.EthereumAddressInfo]: + response = actions.get_ethereum_address_info(db_session, address) + return response + + @app.get( "/addresses", tags=["address info"], response_model=data.AddressListLabelsResponse ) From b00f3958e4a5fba608bbff4319ad73b512f6e3c3 Mon Sep 17 00:00:00 2001 From: Tim Pechersky Date: Thu, 26 Aug 2021 12:09:14 +0200 Subject: [PATCH 02/19] content changes --- frontend/pages/product/index.js | 80 +-------------------------------- 1 file changed, 1 insertion(+), 79 deletions(-) diff --git a/frontend/pages/product/index.js b/frontend/pages/product/index.js index 1057ec3d..09b0fdcc 100644 --- a/frontend/pages/product/index.js +++ b/frontend/pages/product/index.js @@ -7,8 +7,6 @@ import { Stack, chakra, useMediaQuery, - UnorderedList, - ListItem, useBreakpointValue, } from "@chakra-ui/react"; import { DEFAULT_METATAGS, AWS_ASSETS_PATH } from "../../src/core/constants"; @@ -135,7 +133,7 @@ const Product = () => { > - {`Why you'll love moonstream`} + {`Why you'll love Moonstream`} @@ -191,82 +189,6 @@ const Product = () => { - - - Product - - - - Moonstream is a product which helps anyone participate in - decentralized finance. From the most sophisticated flash - arbitrageurs to people looking for yield from currency that would - otherwise lie dormant in their exchange accounts. - - - We aim to go far beyond raw transaction information, enriching our - view with context from centralized exchanges, the news, social - media, and smart contract analysis. - - - Moonstream users can subscribe to events from any blockchain - from - the activity of specific accounts or smart contracts to updates - about general market movements. This information comes from the - blockchains themselves, from their mempools/transaction{" "} - pools, and from centralized exchanges, social media, and the news. - This forms a stream of information tailored to their specific needs. - - - They can use this information to execute transactions directly from - the Moonstream frontend or they can set up programs which execute - (on- or off-chain) when their stream meets certain conditions. - - - Moonstream will be accessible to software through our API and - webhooks. - - - Moonstream customers are: - - - Development teams deploying decentralized applications - - They use Moonstream to analyze how users are calling their - dapps, and set up alerts for suspicious activity.{" "} - - - Algorithmic funds - They use Moonstream to execute - transactions directly on-chain under prespecified conditions. - - - Crypto traders - They use Moonstream to evaluate trading - strategies based on data from centralized exchanges, the - blockchain, and the transaction pool. - - - - - Moonstream’s financial inclusion goes beyond providing access to - data. We also help validators and stakers on proof of stake chains - earn rewards in excess of the validation rewards. We pay validators - to send mempool/transaction pool data back to Moonstream, and they - divide these payments between themselves and their stakers. This - helps validators attract more stake on proof of stake blockchains - like Algorand, Solana, and post-merge Ethereum. It also ensures that - Moonstream users have access to the freshest and most geographically - diverse transaction pool data on the market. - - - All of our work is open source as we do not believe that proprietary - technologies are financially inclusive.{" "} - - You can read our code on GitHub. - - - - ); }; From d031b4c3db1615c7d763399c05a6659a828846af Mon Sep 17 00:00:00 2001 From: yhtiyar Date: Thu, 26 Aug 2021 14:09:19 +0300 Subject: [PATCH 03/19] enum fix --- backend/moonstream/actions.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/backend/moonstream/actions.py b/backend/moonstream/actions.py index 38c20398..cbb59a44 100644 --- a/backend/moonstream/actions.py +++ b/backend/moonstream/actions.py @@ -272,10 +272,10 @@ class AdressType: EXCHANGE = 3 -class LabelNames(Enum): +class LabelNames: ETHERSCAN_SMARTCONTRACT = "etherscan_smartcontract" COINMARKETCAP_TOKEN = "coinmarketcap_token" - EXCHANGE = "EXCANGE" + EXCHANGE = "excange" def get_ethereum_address_info( @@ -307,6 +307,8 @@ def get_ethereum_address_info( address_info.address_type = AdressType.EXCHANGE address_info.details.name = label.label_data["name"] address_info.details.symbol = label.label_data["label"] + else: + print(f"unknown label {label.label}") return address_info From 2f427b2cfcdd753ade7b9dbf2dca2736e5118d0a Mon Sep 17 00:00:00 2001 From: Tim Pechersky Date: Thu, 26 Aug 2021 13:58:44 +0200 Subject: [PATCH 04/19] fix side image gets too big --- frontend/pages/team/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/pages/team/index.js b/frontend/pages/team/index.js index 2500d844..e53eb209 100644 --- a/frontend/pages/team/index.js +++ b/frontend/pages/team/index.js @@ -155,7 +155,6 @@ const Product = () => { Date: Thu, 26 Aug 2021 15:18:31 +0200 Subject: [PATCH 05/19] logo layout improvement --- frontend/src/components/LandingNavbar.js | 186 +++++++++++------------ frontend/src/components/Navbar.js | 11 +- 2 files changed, 96 insertions(+), 101 deletions(-) diff --git a/frontend/src/components/LandingNavbar.js b/frontend/src/components/LandingNavbar.js index a744a5be..6437e7d6 100644 --- a/frontend/src/components/LandingNavbar.js +++ b/frontend/src/components/LandingNavbar.js @@ -1,13 +1,13 @@ import React, { Fragment, useContext } from "react"; import RouterLink from "next/link"; import { - Flex, Button, Image, ButtonGroup, Spacer, Link, IconButton, + Flex, } from "@chakra-ui/react"; import { HamburgerIcon } from "@chakra-ui/icons"; import useModals from "../core/hooks/useModals"; @@ -22,107 +22,107 @@ const LandingNavbar = () => { const { toggleModal } = useModals(); return ( <> - <> - {ui.isMobileView && ( - <> - ui.setSidebarToggled(!ui.sidebarToggled)} - icon={} - /> - - )} - - - - Moonstream logo - - - + {ui.isMobileView && ( + <> + ui.setSidebarToggled(!ui.sidebarToggled)} + icon={} + /> + + )} + - {!ui.isMobileView && ( - <> - - - {ALL_NAV_PATHES.map((item, idx) => ( - - {item.title} - - ))} + {!ui.isMobileView && ( + <> + + + {ALL_NAV_PATHES.map((item, idx) => ( + + {item.title} + + ))} - {ui.isLoggedIn && ( - - - - )} - {!ui.isLoggedIn && ( + {ui.isLoggedIn && ( + - )} - {!ui.isLoggedIn && ( - - )} - {ui.isLoggedIn && ( - - )} - - - )} - {ui.isLoggedIn && ui.isMobileView && ( - <> - - - - )} - + + )} + {!ui.isLoggedIn && ( + + )} + {!ui.isLoggedIn && ( + + )} + {ui.isLoggedIn && ( + + )} + + + )} + {ui.isLoggedIn && ui.isMobileView && ( + <> + + + + )} ); }; diff --git a/frontend/src/components/Navbar.js b/frontend/src/components/Navbar.js index 20d9bedc..7d6cc257 100644 --- a/frontend/src/components/Navbar.js +++ b/frontend/src/components/Navbar.js @@ -19,16 +19,11 @@ const Navbar = () => { boxShadow={["sm", "md"]} alignItems="center" id="Navbar" - minH={["3rem", "3rem", "3rem", "3rem", "3rem", "3rem"]} - // overflow="initial" + minH="3rem" + maxH="3rem" bgColor="primary.1200" - // flexWrap="wrap" - direction={["row", "row", "row", null, "row"]} - // zIndex={100} + direction="row" w="100%" - minW="100%" - m={0} - p={0} overflow="hidden" > From 99a486f91f46285f612f06622cd9c2e457d2c4aa Mon Sep 17 00:00:00 2001 From: Tim Pechersky Date: Thu, 26 Aug 2021 15:18:48 +0200 Subject: [PATCH 06/19] logo preconnect on all routes --- frontend/pages/_app.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/frontend/pages/_app.js b/frontend/pages/_app.js index 44ad346c..9a95bef1 100644 --- a/frontend/pages/_app.js +++ b/frontend/pages/_app.js @@ -21,6 +21,7 @@ const DefaultLayout = dynamic(() => import("../src/layouts"), { }); import { useRouter } from "next/router"; import NProgress from "nprogress"; +import { WHITE_LOGO_W_TEXT_URL } from "../src/core/constants"; export default function CachingApp({ Component, pageProps }) { const [queryClient] = useState(new QueryClient()); @@ -48,6 +49,11 @@ export default function CachingApp({ Component, pageProps }) { const getLayout = Component.getLayout || ((page) => {page}); + const headLinks = [ + { rel: "preload", as: "image", href: WHITE_LOGO_W_TEXT_URL }, + ]; + pageProps.preloads && headLinks.push(...pageProps.preloads); + console.log(headLinks); return ( <> {pageProps.metaTags && } - {pageProps.preloads && } + {getLayout()} From 53a16eb5cc003e75a2d7edaf20d65aaac6fd24bc Mon Sep 17 00:00:00 2001 From: Andrey Dolgolev Date: Thu, 26 Aug 2021 16:21:23 +0300 Subject: [PATCH 07/19] Add or condition by addresses. --- backend/moonstream/providers/bugout.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/backend/moonstream/providers/bugout.py b/backend/moonstream/providers/bugout.py index 57b7d1fb..48e07e97 100644 --- a/backend/moonstream/providers/bugout.py +++ b/backend/moonstream/providers/bugout.py @@ -91,10 +91,24 @@ class BugoutEventProvider: """ is_query_constrained = query.subscription_types or query.subscriptions relevant_subscriptions = user_subscriptions.get(self.event_type) + if ( is_query_constrained and self.event_type not in query.subscription_types ) or not relevant_subscriptions: return None + + if self.event_type == "ethereum_txpool": + addresses = [ + subscription.resource_data["address"] + for subscription in relevant_subscriptions + ] + subscriptions_filters = [] + for adress in addresses: + subscriptions_filters.extend( + [f"?#from_address:{adress}", f"?#to_address:{adress}"] + ) + + return subscriptions_filters return [] def get_events( From a4ed21314cd7c7948f45ad9670d6ac6b2b2b58a2 Mon Sep 17 00:00:00 2001 From: Tim Pechersky Date: Thu, 26 Aug 2021 15:45:01 +0200 Subject: [PATCH 08/19] remove consolelog --- frontend/pages/_app.js | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/pages/_app.js b/frontend/pages/_app.js index 9a95bef1..b4e2894c 100644 --- a/frontend/pages/_app.js +++ b/frontend/pages/_app.js @@ -53,7 +53,6 @@ export default function CachingApp({ Component, pageProps }) { { rel: "preload", as: "image", href: WHITE_LOGO_W_TEXT_URL }, ]; pageProps.preloads && headLinks.push(...pageProps.preloads); - console.log(headLinks); return ( <>