From 0631e2fb95081aa6889f28f1b75fc0e3fd9a6cb2 Mon Sep 17 00:00:00 2001 From: Andrey Dolgolev Date: Thu, 12 Aug 2021 16:39:26 +0300 Subject: [PATCH 1/6] Fix issues. 1) issue with enpty value in filter 2) issue with empty value in ethrium transaction request Add 1) Add urlencoding and replace null to 0 for timestamps 2) Add sorting by timestamps --- backend/moonstream/actions.py | 13 +++++--- backend/moonstream/routes/streams.py | 8 ++--- frontend/src/components/EntriesNavigation.js | 34 +++++++++++--------- frontend/src/components/SubscriptionsList.js | 2 +- frontend/src/core/hooks/useStream.js | 1 + frontend/src/core/services/stream.service.js | 8 ++--- 6 files changed, 36 insertions(+), 30 deletions(-) diff --git a/backend/moonstream/actions.py b/backend/moonstream/actions.py index c6cd028d..0b459577 100644 --- a/backend/moonstream/actions.py +++ b/backend/moonstream/actions.py @@ -84,6 +84,8 @@ async def get_transaction_in_blocks( .filter(filters) ) + ethereum_transactions = ethereum_transactions_in_subscriptions + # If not start_time and end_time not present # Get latest transaction if boundaries.end_time == 0: @@ -92,10 +94,11 @@ async def get_transaction_in_blocks( text("timestamp desc") ).limit(1) ).one_or_none() - boundaries.end_time = ethereum_transaction_start_point[-1] - boundaries.start_time = ( - ethereum_transaction_start_point[-1] - DEFAULT_STREAM_TIMEINTERVAL - ) + if ethereum_transaction_start_point: + boundaries.end_time = ethereum_transaction_start_point[-1] + boundaries.start_time = ( + ethereum_transaction_start_point[-1] - DEFAULT_STREAM_TIMEINTERVAL + ) if boundaries.start_time != 0 and boundaries.end_time != 0: if boundaries.start_time > boundaries.end_time: @@ -105,7 +108,7 @@ async def get_transaction_in_blocks( ) if boundaries.end_time: - ethereum_transactions = ethereum_transactions_in_subscriptions.filter( + ethereum_transactions = ethereum_transactions.filter( include_or_not_lower( EthereumBlock.timestamp, boundaries.include_end, boundaries.end_time ) diff --git a/backend/moonstream/routes/streams.py b/backend/moonstream/routes/streams.py index 579154ca..e60e65d5 100644 --- a/backend/moonstream/routes/streams.py +++ b/backend/moonstream/routes/streams.py @@ -60,10 +60,10 @@ app.add_middleware(BroodAuthMiddleware, whitelist=whitelist_paths) async def search_transactions( request: Request, q: str = Query(""), - start_time: Optional[int] = Query(0), # Optional[int] = Query(0), # - end_time: Optional[int] = Query(0), # Optional[int] = Query(0), # - include_start: bool = Query(False), - include_end: bool = Query(False), + start_time: Optional[int] = Query(0), + end_time: Optional[int] = Query(0), + include_start: Optional[bool] = Query(False), + include_end: Optional[bool] = Query(False), db_session: Session = Depends(db.yield_db_session), ): diff --git a/frontend/src/components/EntriesNavigation.js b/frontend/src/components/EntriesNavigation.js index f08df544..334996d4 100644 --- a/frontend/src/components/EntriesNavigation.js +++ b/frontend/src/components/EntriesNavigation.js @@ -80,8 +80,8 @@ const EntriesNavigation = () => { const loadMoreButtonRef = useRef(null); const [streamBoundary, setStreamBoundary] = useState({ - start_time: null, - end_time: null, + start_time: 0, + end_time: 0, include_start: false, include_end: true, next_event_time: null, @@ -192,7 +192,7 @@ const EntriesNavigation = () => { useEffect(() => { if ( subscriptionsCache.data?.subscriptions[0]?.id && - newFilterState[0].value === null + newFilterState[0]?.value === null ) { setFilterProps(0, { value: subscriptionsCache?.data?.subscriptions[0]?.address, @@ -514,8 +514,8 @@ const EntriesNavigation = () => { onClick={() => { remove(); setStreamBoundary({ - start_time: null, - end_time: null, + start_time: 0, + end_time: 0, include_start: false, include_end: true, next_event_time: null, @@ -556,17 +556,19 @@ const EntriesNavigation = () => { "" // some strange behaivior without else condition return 0 wich can see on frontend page )} - {entries.map((entry, idx) => ( - - ))} - {streamBoundary.previous_event_time || isFetching ? ( + {entries + ?.sort((a, b) => b.timestamp - a.timestamp) + .map((entry, idx) => ( + + ))} + {streamBoundary.previous_event_time && !isFetching ? (
) : ( - "" +
+ {!isFetching ? ( + "Тransactions not found. You can subscribe to more addresses in Subscriptions menu." + ) : ( + + )} +
)} - {streamBoundary.previous_event_time && isLoading && ( + {streamBoundary.previous_event_time && isLoading ? (
+ ) : ( + "" )} diff --git a/frontend/src/core/services/stream.service.js b/frontend/src/core/services/stream.service.js index 6a2f5855..60995a25 100644 --- a/frontend/src/core/services/stream.service.js +++ b/frontend/src/core/services/stream.service.js @@ -9,15 +9,32 @@ export const getStream = ({ end_time, include_start, include_end, -}) => - http({ +}) => { + let params = {}; + + if (searchTerm) { + params.q = encodeURIComponent(searchTerm); + } + + if (start_time) { + params.start_time = encodeURIComponent(start_time); + } + + if (end_time) { + params.end_time = encodeURIComponent(end_time); + } + + if (include_start) { + params.include_start = encodeURIComponent(true); + } + + if (include_end) { + params.include_end = encodeURIComponent(true); + } + + return http({ method: "GET", url: `${API}/streams/`, - params: { - q: searchTerm, - start_time: encodeURIComponent(start_time), - end_time: encodeURIComponent(end_time), - include_start: encodeURIComponent(include_start), - include_end: encodeURIComponent(include_end), - }, + params: params, }); +}; From 3905ae1fa8b6b1b7f9c13fe87026dd8d63512bce Mon Sep 17 00:00:00 2001 From: Neeraj Kashyap Date: Fri, 13 Aug 2021 05:17:31 -0700 Subject: [PATCH 4/6] Fixed typo on landing page: "ment" -> "meant" --- frontend/pages/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/pages/index.js b/frontend/pages/index.js index 28988fba..a1d8fc69 100644 --- a/frontend/pages/index.js +++ b/frontend/pages/index.js @@ -335,7 +335,7 @@ const Homepage = () => {
- Moonstream is ment for you if + Moonstream is meant for you if
Date: Fri, 13 Aug 2021 06:41:26 -0700 Subject: [PATCH 5/6] Improved main README for the repo --- README.md | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index bd12b7b0..5fc88902 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,59 @@ # moonstream -The Bugout blockchain inspector + +\[[Live at https://moonstream.to/](https://moonstream.to)\] | \[[Join us on Discord](https://discord.gg/pYE65FuNSz)\] + +## What is Moonstream? + +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. + +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. + +## Who uses Moonstream? + +1. **Development teams deploying decentralized applications.** They use Moonstream to analyze how + users are calling their dapps, and set up alerts for suspicious activity. +2. **Algorithmic funds.** They use Moonstream to execute transactions directly on-chain under + prespecified conditions. +3. **Crypto traders.** They use Moonstream to evaluate trading strategies based on data from + centralized exchanges, the blockchain, and the transaction pool. + +## Free software + +Proprietary technologies are not inclusive technologies, and we believe in inclusion. + +All of our technology is open source. This repository contains all the code that powers +https://moonstream.to. The code is licensed with the [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0). + +You are and _will always be_ free to host your own instance of Moonstream. + +## Architecture + +This monorepo contains the following components: + +1. [`frontend`](./frontend): A web frontend for Moonstream. Allows users to perform API operations + through a visual interface. The frontend also offers charting and analysis functionality. Built + in [React](https://reactjs.org/). +2. [`backend`'](./backend): The Moonstream API. This portion of the code base implements a REST API + through which users can manage the events that show up in their stream and actually consume their + stream data. Built in [Python](https://www.python.org/) using [Fast API](https://fastapi.tiangolo.com/). +3. [`crawlers`](./crawlers): This part of the code base contains workers which extract data from + blockchains, transaction pools, and other sources. Currently contains a single [Python](https://www.python.org/) + package but we will soon be addding crawlers implemented in other languages: [Go](https://golang.org/), + [Rust](https://www.rust-lang.org/)), and [Javascript](https://developer.mozilla.org/en-US/docs/Web/JavaScript). +4. [`db`](./db): Moonstream stores blockchain data in [Postgres](https://www.postgresql.org/). This + directory contains the code we use to manage the schema in our Postgres database. For sources that + send higher volumes of data, we use a separate Postgres database and interface with it using + [Bugout](https://bugout.dev). For more information on how that data is processed, check how the API + inserts events from those sources into a stream. + +## Contributing + +If you would like to contribute to Moonstream, please reach out to @zomglings on the [Moonstream Discord](https://discord.gg/pYE65FuNSz). From ddb1b71104c4c8596aae502d69950bc41bef2460 Mon Sep 17 00:00:00 2001 From: Neeraj Kashyap Date: Fri, 13 Aug 2021 08:47:58 -0700 Subject: [PATCH 6/6] Fixed issues with stream requests to backend --- .../src/core/providers/UIProvider/index.js | 2 +- frontend/src/core/services/stream.service.js | 26 +++++++------------ 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/frontend/src/core/providers/UIProvider/index.js b/frontend/src/core/providers/UIProvider/index.js index 9beb3ada..9bdf23da 100644 --- a/frontend/src/core/providers/UIProvider/index.js +++ b/frontend/src/core/providers/UIProvider/index.js @@ -28,7 +28,7 @@ const UIProvider = ({ children }) => { }); const { modal, toggleModal } = useContext(ModalContext); - const [searchTerm, setSearchTerm] = useQuery("q", " ", true, false); + const [searchTerm, setSearchTerm] = useQuery("q", "", true, false); const [entryId, setEntryId] = useState(); diff --git a/frontend/src/core/services/stream.service.js b/frontend/src/core/services/stream.service.js index 60995a25..3461a47c 100644 --- a/frontend/src/core/services/stream.service.js +++ b/frontend/src/core/services/stream.service.js @@ -10,31 +10,25 @@ export const getStream = ({ include_start, include_end, }) => { - let params = {}; - - if (searchTerm) { - params.q = encodeURIComponent(searchTerm); + let params = { + q: searchTerm, + }; + if (start_time || start_time === 0) { + params.start_time = start_time; } - - if (start_time) { - params.start_time = encodeURIComponent(start_time); + if (end_time || end_time === 0) { + params.end_time = end_time; } - - if (end_time) { - params.end_time = encodeURIComponent(end_time); - } - if (include_start) { - params.include_start = encodeURIComponent(true); + params.include_start = include_start; } - if (include_end) { - params.include_end = encodeURIComponent(true); + params.include_end = include_end; } return http({ method: "GET", url: `${API}/streams/`, - params: params, + params, }); };