Merge branch 'main' into cards-improvement

pull/99/head
Tim Pechersky 2021-08-13 18:24:31 +02:00
commit 5a8a9c7095
9 zmienionych plików z 123 dodań i 41 usunięć

Wyświetl plik

@ -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).

Wyświetl plik

@ -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
)

Wyświetl plik

@ -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),
):
@ -87,8 +87,6 @@ async def search_transactions(
for resource in user_subscriptions_resources.resources
}
# transactions: List[Any] = []
boundaries = data.PageBoundary(
start_time=start_time,
end_time=end_time,
@ -97,17 +95,14 @@ async def search_transactions(
include_start=include_start,
include_end=include_end,
)
print(boundaries)
if address_to_subscriptions:
print("address_to_subscriptions")
response = await actions.get_transaction_in_blocks(
db_session=db_session,
query=q,
user_subscriptions_resources_by_address=address_to_subscriptions,
boundaries=boundaries,
)
print(response.boundaries)
return response
else:

Wyświetl plik

@ -335,7 +335,7 @@ const Homepage = () => {
</SimpleGrid>
<Center>
<Heading pt="160px" pb="60px">
Moonstream is ment for you if
Moonstream is meant for you if
</Heading>
</Center>
<Flex

Wyświetl plik

@ -175,7 +175,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,
@ -525,17 +525,19 @@ const EntriesNavigation = () => {
"" // some strange behaivior without else condition return 0 wich can see on frontend page
)}
</Stack>
{entries.map((entry, idx) => (
<StreamEntry
key={`entry-list-${idx}`}
entry={entry}
disableDelete={!canDelete}
disableCopy={!canCreate}
filterCallback={handleFilterStateCallback}
filterConstants={{ DIRECTIONS, CONDITION, FILTER_TYPES }}
/>
))}
{streamBoundary.previous_event_time || isFetching ? (
{entries
?.sort((a, b) => b.timestamp - a.timestamp) // TODO(Andrey) improve that for bi chunks of data sorting can take time
.map((entry, idx) => (
<StreamEntry
key={`entry-list-${idx}`}
entry={entry}
disableDelete={!canDelete}
disableCopy={!canCreate}
filterCallback={handleFilterStateCallback}
filterConstants={{ DIRECTIONS, CONDITION, FILTER_TYPES }}
/>
))}
{streamBoundary.previous_event_time && !isFetching ? (
<Center>
<Button
onClick={() => {
@ -553,9 +555,20 @@ const EntriesNavigation = () => {
</Button>
</Center>
) : (
""
<Center>
{!isFetching ? (
"Тransactions not found. You can subscribe to more addresses in Subscriptions menu."
) : (
<Button
isLoading
loadingText="Loading"
variant="outline"
colorScheme="suggested"
></Button>
)}
</Center>
)}
{streamBoundary.previous_event_time && isLoading && (
{streamBoundary.previous_event_time && isLoading ? (
<Center>
<Spinner
//hidden={!isFetchingMore}
@ -567,6 +580,8 @@ const EntriesNavigation = () => {
speed="1.5s"
/>
</Center>
) : (
""
)}
</Flex>
</Flex>

Wyświetl plik

@ -59,7 +59,7 @@ const SubscriptionsList = () => {
{subscriptionsCache.data.subscriptions.map((subscription) => {
let iconLink;
switch (subscription.subscription_type_id) {
case "1":
case "0":
iconLink =
"https://ethereum.org/static/c48a5f760c34dfadcf05a208dab137cc/31987/eth-diamond-rainbow.png";
break;

Wyświetl plik

@ -41,6 +41,7 @@ const useJournalEntries = ({
//refetchInterval: refreshRate,
...queryCacheProps,
keepPreviousData: true,
retry: 3,
onSuccess: (response) => {
// response is object which return condition in getStream
// TODO(andrey): Response should send page parameters inside "boundary" object (can be null).

Wyświetl plik

@ -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 [searchBarActive, setSearchBarActive] = useState(false);

Wyświetl plik

@ -9,15 +9,26 @@ export const getStream = ({
end_time,
include_start,
include_end,
}) =>
http({
}) => {
let params = {
q: searchTerm,
};
if (start_time || start_time === 0) {
params.start_time = start_time;
}
if (end_time || end_time === 0) {
params.end_time = end_time;
}
if (include_start) {
params.include_start = include_start;
}
if (include_end) {
params.include_end = include_end;
}
return http({
method: "GET",
url: `${API}/streams/`,
params: {
q: searchTerm,
start_time: start_time,
end_time: end_time,
include_start: include_start,
include_end: include_end,
},
params,
});
};