kopia lustrzana https://github.com/bugout-dev/moonstream
Merge branch 'main' into change-navbar-logo
commit
ed641fb67d
|
@ -19,9 +19,9 @@ jobs:
|
||||||
- name: Install test requirements
|
- name: Install test requirements
|
||||||
working-directory: ./backend
|
working-directory: ./backend
|
||||||
run: pip install -r requirements.txt
|
run: pip install -r requirements.txt
|
||||||
# - name: Mypy type check
|
- name: Mypy type check
|
||||||
# working-directory: ./backend
|
working-directory: ./backend
|
||||||
# run: mypy moonstream/
|
run: mypy moonstream/
|
||||||
- name: Black syntax check
|
- name: Black syntax check
|
||||||
working-directory: ./backend
|
working-directory: ./backend
|
||||||
run: black --check moonstream/
|
run: black --check moonstream/
|
||||||
|
|
|
@ -19,9 +19,9 @@ jobs:
|
||||||
- name: Install test requirements
|
- name: Install test requirements
|
||||||
working-directory: ./crawlers
|
working-directory: ./crawlers
|
||||||
run: pip install -e .[dev]
|
run: pip install -e .[dev]
|
||||||
# - name: Mypy type check
|
- name: Mypy type check
|
||||||
# working-directory: ./crawlers
|
working-directory: ./crawlers
|
||||||
# run: mypy mooncrawl/
|
run: mypy mooncrawl/
|
||||||
- name: Black syntax check
|
- name: Black syntax check
|
||||||
working-directory: ./crawlers
|
working-directory: ./crawlers
|
||||||
run: black --check mooncrawl/
|
run: black --check mooncrawl/
|
||||||
|
|
|
@ -19,9 +19,9 @@ jobs:
|
||||||
- name: Install test requirements
|
- name: Install test requirements
|
||||||
working-directory: ./db
|
working-directory: ./db
|
||||||
run: pip install -e .[dev]
|
run: pip install -e .[dev]
|
||||||
# - name: Mypy type check
|
- name: Mypy type check
|
||||||
# working-directory: ./db
|
working-directory: ./db
|
||||||
# run: mypy moonstreamdb/
|
run: mypy moonstreamdb/
|
||||||
- name: Black syntax check
|
- name: Black syntax check
|
||||||
working-directory: ./db
|
working-directory: ./db
|
||||||
run: black --check moonstreamdb/
|
run: black --check moonstreamdb/
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
from datetime import datetime
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
from typing import Dict, Any, List, Optional
|
||||||
|
|
||||||
|
import boto3 # type: ignore
|
||||||
from typing import Dict, Any, List, Optional, Union
|
|
||||||
|
|
||||||
from sqlalchemy.engine.base import Transaction
|
|
||||||
from moonstreamdb.models import (
|
from moonstreamdb.models import (
|
||||||
EthereumBlock,
|
EthereumBlock,
|
||||||
EthereumTransaction,
|
EthereumTransaction,
|
||||||
EthereumPendingTransaction,
|
|
||||||
EthereumAddress,
|
EthereumAddress,
|
||||||
EthereumLabel,
|
EthereumLabel,
|
||||||
)
|
)
|
||||||
|
@ -16,12 +13,10 @@ from sqlalchemy import or_, and_, text
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from . import data
|
from . import data
|
||||||
|
|
||||||
from .settings import DEFAULT_STREAM_TIMEINTERVAL, ETHERSCAN_SMARTCONTRACTS_BUCKET
|
from .settings import DEFAULT_STREAM_TIMEINTERVAL, ETHERSCAN_SMARTCONTRACTS_BUCKET
|
||||||
import boto3
|
|
||||||
import json
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
ETHERSCAN_SMARTCONTRACT_LABEL_NAME = "etherscan_smartcontract"
|
||||||
|
|
||||||
|
|
||||||
async def get_transaction_in_blocks(
|
async def get_transaction_in_blocks(
|
||||||
|
@ -264,7 +259,7 @@ def parse_search_query_to_sqlalchemy_filters(q: str, allowed_addresses: List[str
|
||||||
return constructed_filters
|
return constructed_filters
|
||||||
|
|
||||||
|
|
||||||
def get_source_code(
|
def get_contract_source_info(
|
||||||
db_session: Session, contract_address: str
|
db_session: Session, contract_address: str
|
||||||
) -> Optional[data.EthereumSmartContractSourceInfo]:
|
) -> Optional[data.EthereumSmartContractSourceInfo]:
|
||||||
query = db_session.query(EthereumAddress.id).filter(
|
query = db_session.query(EthereumAddress.id).filter(
|
||||||
|
@ -278,7 +273,7 @@ def get_source_code(
|
||||||
)
|
)
|
||||||
|
|
||||||
for label in labels:
|
for label in labels:
|
||||||
if label.label == "etherscan_smartcontract":
|
if label.label == ETHERSCAN_SMARTCONTRACT_LABEL_NAME:
|
||||||
object_uri = label.label_data["object_uri"]
|
object_uri = label.label_data["object_uri"]
|
||||||
key = object_uri.split("s3://etherscan-smart-contracts/")[1]
|
key = object_uri.split("s3://etherscan-smart-contracts/")[1]
|
||||||
s3 = boto3.client("s3")
|
s3 = boto3.client("s3")
|
||||||
|
@ -294,13 +289,13 @@ def get_source_code(
|
||||||
)
|
)
|
||||||
return contract_source_info
|
return contract_source_info
|
||||||
except:
|
except:
|
||||||
logger.error(f"Failed to load smart contract {contract_address}")
|
logger.error(f"Failed to load smart contract {object_uri}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def get_address_labels(
|
def get_address_labels(
|
||||||
db_session: Session, start: int, limit: int, addresses: Optional[List[str]] = None
|
db_session: Session, start: int, limit: int, addresses: Optional[str] = None
|
||||||
) -> List[EthereumAddress]:
|
) -> data.AddressListLabelsResponse:
|
||||||
"""
|
"""
|
||||||
Attach labels to addresses.
|
Attach labels to addresses.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -84,11 +84,13 @@ async def txinfo_ethereum_blockchain_handler(
|
||||||
if smart_contract is not None:
|
if smart_contract is not None:
|
||||||
response.is_smart_contract_deployment = True
|
response.is_smart_contract_deployment = True
|
||||||
else:
|
else:
|
||||||
response.smart_contract_info = actions.get_source_code(
|
source_info = actions.get_contract_source_info(
|
||||||
db_session, txinfo_request.tx.to_address
|
db_session, txinfo_request.tx.to_address
|
||||||
)
|
)
|
||||||
response.smart_contract_address = txinfo_request.tx.to_address
|
if source_info is not None:
|
||||||
response.is_smart_contract_call = True
|
response.smart_contract_info = source_info
|
||||||
|
response.smart_contract_address = txinfo_request.tx.to_address
|
||||||
|
response.is_smart_contract_call = True
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
@ -97,8 +99,8 @@ async def txinfo_ethereum_blockchain_handler(
|
||||||
)
|
)
|
||||||
async def addresses_labels_handler(
|
async def addresses_labels_handler(
|
||||||
addresses: Optional[str] = Query(None),
|
addresses: Optional[str] = Query(None),
|
||||||
start: Optional[int] = Query(0),
|
start: int = Query(0),
|
||||||
limit: Optional[int] = Query(100),
|
limit: int = Query(100),
|
||||||
db_session: Session = Depends(yield_db_session),
|
db_session: Session = Depends(yield_db_session),
|
||||||
) -> data.AddressListLabelsResponse:
|
) -> data.AddressListLabelsResponse:
|
||||||
"""
|
"""
|
||||||
|
@ -110,11 +112,11 @@ async def addresses_labels_handler(
|
||||||
status_code=406, detail="The limit cannot exceed 100 addresses"
|
status_code=406, detail="The limit cannot exceed 100 addresses"
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
addresses = actions.get_address_labels(
|
addresses_response = actions.get_address_labels(
|
||||||
db_session=db_session, start=start, limit=limit, addresses=addresses
|
db_session=db_session, start=start, limit=limit, addresses=addresses
|
||||||
)
|
)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
logger.error(f"Unable to get info about Ethereum addresses {err}")
|
logger.error(f"Unable to get info about Ethereum addresses {err}")
|
||||||
raise HTTPException(status_code=500)
|
raise HTTPException(status_code=500)
|
||||||
|
|
||||||
return addresses
|
return addresses_response
|
||||||
|
|
|
@ -16,8 +16,8 @@ MOONSTREAM_DATA_JOURNAL_ID = os.environ.get("MOONSTREAM_DATA_JOURNAL_ID")
|
||||||
if MOONSTREAM_DATA_JOURNAL_ID is None:
|
if MOONSTREAM_DATA_JOURNAL_ID is None:
|
||||||
raise ValueError("MOONSTREAM_DATA_JOURNAL_ID environment variable must be set")
|
raise ValueError("MOONSTREAM_DATA_JOURNAL_ID environment variable must be set")
|
||||||
|
|
||||||
MOONSTREAM_ADMIN_ACCESS_TOKEN = os.environ.get("MOONSTREAM_ADMIN_ACCESS_TOKEN")
|
MOONSTREAM_ADMIN_ACCESS_TOKEN = os.environ.get("MOONSTREAM_ADMIN_ACCESS_TOKEN", "")
|
||||||
if MOONSTREAM_ADMIN_ACCESS_TOKEN is None:
|
if MOONSTREAM_ADMIN_ACCESS_TOKEN == "":
|
||||||
raise ValueError("MOONSTREAM_ADMIN_ACCESS_TOKEN environment variable must be set")
|
raise ValueError("MOONSTREAM_ADMIN_ACCESS_TOKEN environment variable must be set")
|
||||||
|
|
||||||
# Origin
|
# Origin
|
||||||
|
@ -43,4 +43,6 @@ for path in MOONSTREAM_OPENAPI_LIST:
|
||||||
DEFAULT_STREAM_TIMEINTERVAL = 5 * 60
|
DEFAULT_STREAM_TIMEINTERVAL = 5 * 60
|
||||||
|
|
||||||
# S3 Bucket
|
# S3 Bucket
|
||||||
ETHERSCAN_SMARTCONTRACTS_BUCKET = "etherscan-smart-contracts"
|
ETHERSCAN_SMARTCONTRACTS_BUCKET = os.environ.get("AWS_S3_SMARTCONTRACT_BUCKET")
|
||||||
|
if ETHERSCAN_SMARTCONTRACTS_BUCKET is None:
|
||||||
|
raise ValueError("AWS_S3_SMARTCONTRACT_BUCKET is not set")
|
||||||
|
|
|
@ -5,5 +5,6 @@ export MOONSTREAM_DATA_JOURNAL_ID="<bugout_journal_id_to_store_blockchain_data>"
|
||||||
export MOONSTREAM_DB_URI="postgresql://<username>:<password>@<db_host>:<db_port>/<db_name>"
|
export MOONSTREAM_DB_URI="postgresql://<username>:<password>@<db_host>:<db_port>/<db_name>"
|
||||||
export MOONSTREAM_POOL_SIZE=0
|
export MOONSTREAM_POOL_SIZE=0
|
||||||
export MOONSTREAM_ADMIN_ACCESS_TOKEN="<Access token to application resources>"
|
export MOONSTREAM_ADMIN_ACCESS_TOKEN="<Access token to application resources>"
|
||||||
|
export AWS_S3_SMARTCONTRACT_BUCKET=""
|
||||||
export BUGOUT_BROOD_URL="https://auth.bugout.dev"
|
export BUGOUT_BROOD_URL="https://auth.bugout.dev"
|
||||||
export BUGOUT_SPIRE_URL="https://spire.bugout.dev"
|
export BUGOUT_SPIRE_URL="https://spire.bugout.dev"
|
||||||
|
|
|
@ -91,6 +91,8 @@ def ethcrawler_blocks_sync_handler(args: argparse.Namespace) -> None:
|
||||||
starting_block: int = args.start
|
starting_block: int = args.start
|
||||||
while True:
|
while True:
|
||||||
bottom_block_number, top_block_number = get_latest_blocks(args.confirmations)
|
bottom_block_number, top_block_number = get_latest_blocks(args.confirmations)
|
||||||
|
if bottom_block_number is None:
|
||||||
|
raise ValueError("Variable bottom_block_number can't be None")
|
||||||
bottom_block_number = max(bottom_block_number + 1, starting_block)
|
bottom_block_number = max(bottom_block_number + 1, starting_block)
|
||||||
if bottom_block_number >= top_block_number:
|
if bottom_block_number >= top_block_number:
|
||||||
print(
|
print(
|
||||||
|
|
|
@ -44,9 +44,11 @@ def connect(web3_uri: Optional[str] = MOONSTREAM_IPC_PATH):
|
||||||
return web3_client
|
return web3_client
|
||||||
|
|
||||||
|
|
||||||
def add_block(db_session, block: BlockData) -> None:
|
def add_block(db_session, block: Any) -> None:
|
||||||
"""
|
"""
|
||||||
Add block if doesn't presented in database.
|
Add block if doesn't presented in database.
|
||||||
|
|
||||||
|
block: web3.types.BlockData
|
||||||
"""
|
"""
|
||||||
block_obj = EthereumBlock(
|
block_obj = EthereumBlock(
|
||||||
block_number=block.number,
|
block_number=block.number,
|
||||||
|
@ -70,9 +72,11 @@ def add_block(db_session, block: BlockData) -> None:
|
||||||
db_session.add(block_obj)
|
db_session.add(block_obj)
|
||||||
|
|
||||||
|
|
||||||
def add_block_transactions(db_session, block: BlockData) -> None:
|
def add_block_transactions(db_session, block: Any) -> None:
|
||||||
"""
|
"""
|
||||||
Add block transactions.
|
Add block transactions.
|
||||||
|
|
||||||
|
block: web3.types.BlockData
|
||||||
"""
|
"""
|
||||||
for tx in block.transactions:
|
for tx in block.transactions:
|
||||||
tx_obj = EthereumTransaction(
|
tx_obj = EthereumTransaction(
|
||||||
|
@ -188,7 +192,7 @@ def crawl_blocks_executor(
|
||||||
Returns nothing, but if there was an error processing the given blocks it raises an EthereumBlocksCrawlError.
|
Returns nothing, but if there was an error processing the given blocks it raises an EthereumBlocksCrawlError.
|
||||||
The error message is a list of all the things that went wrong in the crawl.
|
The error message is a list of all the things that went wrong in the crawl.
|
||||||
"""
|
"""
|
||||||
errors: List[Exception] = []
|
errors: List[BaseException] = []
|
||||||
|
|
||||||
def record_error(f: Future) -> None:
|
def record_error(f: Future) -> None:
|
||||||
error = f.exception()
|
error = f.exception()
|
||||||
|
@ -196,7 +200,7 @@ def crawl_blocks_executor(
|
||||||
errors.append(error)
|
errors.append(error)
|
||||||
|
|
||||||
worker_indices = range(MOONSTREAM_CRAWL_WORKERS)
|
worker_indices = range(MOONSTREAM_CRAWL_WORKERS)
|
||||||
worker_job_lists = [[] for _ in worker_indices]
|
worker_job_lists: List[List[Any]] = [[] for _ in worker_indices]
|
||||||
for i, block_number in enumerate(block_numbers_list):
|
for i, block_number in enumerate(block_numbers_list):
|
||||||
worker_job_lists[i % MOONSTREAM_CRAWL_WORKERS].append(block_number)
|
worker_job_lists[i % MOONSTREAM_CRAWL_WORKERS].append(block_number)
|
||||||
|
|
||||||
|
@ -290,6 +294,7 @@ def trending(
|
||||||
end_timestamp = int(date_range.end_time.timestamp())
|
end_timestamp = int(date_range.end_time.timestamp())
|
||||||
|
|
||||||
def make_query(
|
def make_query(
|
||||||
|
db_session: Session,
|
||||||
identifying_column: Column,
|
identifying_column: Column,
|
||||||
statistic_column: Column,
|
statistic_column: Column,
|
||||||
aggregate_func: Callable,
|
aggregate_func: Callable,
|
||||||
|
@ -328,6 +333,7 @@ def trending(
|
||||||
|
|
||||||
try:
|
try:
|
||||||
transactions_out_query = make_query(
|
transactions_out_query = make_query(
|
||||||
|
db_session,
|
||||||
EthereumTransaction.from_address,
|
EthereumTransaction.from_address,
|
||||||
EthereumTransaction.hash,
|
EthereumTransaction.hash,
|
||||||
func.count,
|
func.count,
|
||||||
|
@ -339,6 +345,7 @@ def trending(
|
||||||
]
|
]
|
||||||
|
|
||||||
transactions_in_query = make_query(
|
transactions_in_query = make_query(
|
||||||
|
db_session,
|
||||||
EthereumTransaction.to_address,
|
EthereumTransaction.to_address,
|
||||||
EthereumTransaction.hash,
|
EthereumTransaction.hash,
|
||||||
func.count,
|
func.count,
|
||||||
|
@ -350,6 +357,7 @@ def trending(
|
||||||
]
|
]
|
||||||
|
|
||||||
value_out_query = make_query(
|
value_out_query = make_query(
|
||||||
|
db_session,
|
||||||
EthereumTransaction.from_address,
|
EthereumTransaction.from_address,
|
||||||
EthereumTransaction.value,
|
EthereumTransaction.value,
|
||||||
func.sum,
|
func.sum,
|
||||||
|
@ -361,6 +369,7 @@ def trending(
|
||||||
]
|
]
|
||||||
|
|
||||||
value_in_query = make_query(
|
value_in_query = make_query(
|
||||||
|
db_session,
|
||||||
EthereumTransaction.to_address,
|
EthereumTransaction.to_address,
|
||||||
EthereumTransaction.value,
|
EthereumTransaction.value,
|
||||||
func.sum,
|
func.sum,
|
||||||
|
|
|
@ -1,21 +1,22 @@
|
||||||
import argparse
|
import argparse
|
||||||
import boto3
|
import sys
|
||||||
|
import time
|
||||||
|
from datetime import datetime
|
||||||
|
from typing import Any, List, Optional, Dict
|
||||||
|
from dataclasses import dataclass
|
||||||
import csv
|
import csv
|
||||||
import codecs
|
import codecs
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
from sqlalchemy.orm import Session
|
|
||||||
|
import boto3 # type: ignore
|
||||||
from moonstreamdb.db import yield_db_session_ctx
|
from moonstreamdb.db import yield_db_session_ctx
|
||||||
import sys
|
|
||||||
import time
|
|
||||||
from datetime import datetime
|
|
||||||
from typing import Any, List, Optional, Tuple, Dict
|
|
||||||
from dataclasses import dataclass
|
|
||||||
from sqlalchemy.sql.expression import label, text
|
|
||||||
from .version import MOONCRAWL_VERSION
|
|
||||||
from moonstreamdb.models import EthereumAddress, EthereumLabel
|
from moonstreamdb.models import EthereumAddress, EthereumLabel
|
||||||
import requests
|
import requests
|
||||||
|
from sqlalchemy.orm import Session
|
||||||
|
from sqlalchemy.sql.expression import text
|
||||||
|
|
||||||
|
from .version import MOONCRAWL_VERSION
|
||||||
from .settings import MOONSTREAM_ETHERSCAN_TOKEN
|
from .settings import MOONSTREAM_ETHERSCAN_TOKEN
|
||||||
|
|
||||||
if MOONSTREAM_ETHERSCAN_TOKEN is None:
|
if MOONSTREAM_ETHERSCAN_TOKEN is None:
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from . import cli
|
from . import ethcrawler
|
||||||
|
|
||||||
|
|
||||||
class TestYieldBlockNumbersLists(unittest.TestCase):
|
class TestYieldBlockNumbersLists(unittest.TestCase):
|
||||||
def test_yield_descending_10_6_step_4(self):
|
def test_yield_descending_10_6_step_4(self):
|
||||||
partition = [
|
partition = [
|
||||||
block_numbers_list
|
block_numbers_list
|
||||||
for block_numbers_list in cli.yield_blocks_numbers_lists(
|
for block_numbers_list in ethcrawler.yield_blocks_numbers_lists(
|
||||||
"10-6", block_step=4
|
"10-6", block_step=4
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
@ -16,7 +16,7 @@ class TestYieldBlockNumbersLists(unittest.TestCase):
|
||||||
def test_yield_descending_10_6_step_3(self):
|
def test_yield_descending_10_6_step_3(self):
|
||||||
partition = [
|
partition = [
|
||||||
block_numbers_list
|
block_numbers_list
|
||||||
for block_numbers_list in cli.yield_blocks_numbers_lists(
|
for block_numbers_list in ethcrawler.yield_blocks_numbers_lists(
|
||||||
"10-6", block_step=3
|
"10-6", block_step=3
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
@ -25,8 +25,8 @@ class TestYieldBlockNumbersLists(unittest.TestCase):
|
||||||
def test_yield_descending_10_6_descending_step_3(self):
|
def test_yield_descending_10_6_descending_step_3(self):
|
||||||
partition = [
|
partition = [
|
||||||
block_numbers_list
|
block_numbers_list
|
||||||
for block_numbers_list in cli.yield_blocks_numbers_lists(
|
for block_numbers_list in ethcrawler.yield_blocks_numbers_lists(
|
||||||
"10-6", cli.ProcessingOrder.DESCENDING, 3
|
"10-6", ethcrawler.ProcessingOrder.DESCENDING, 3
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
self.assertListEqual(partition, [[10, 9, 8], [7, 6]])
|
self.assertListEqual(partition, [[10, 9, 8], [7, 6]])
|
||||||
|
@ -34,8 +34,8 @@ class TestYieldBlockNumbersLists(unittest.TestCase):
|
||||||
def test_yield_descending_10_6_descending_step_10(self):
|
def test_yield_descending_10_6_descending_step_10(self):
|
||||||
partition = [
|
partition = [
|
||||||
block_numbers_list
|
block_numbers_list
|
||||||
for block_numbers_list in cli.yield_blocks_numbers_lists(
|
for block_numbers_list in ethcrawler.yield_blocks_numbers_lists(
|
||||||
"10-6", cli.ProcessingOrder.DESCENDING, 10
|
"10-6", ethcrawler.ProcessingOrder.DESCENDING, 10
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
self.assertListEqual(partition, [[10, 9, 8, 7, 6]])
|
self.assertListEqual(partition, [[10, 9, 8, 7, 6]])
|
||||||
|
@ -43,7 +43,7 @@ class TestYieldBlockNumbersLists(unittest.TestCase):
|
||||||
def test_yield_descending_6_10_step_4(self):
|
def test_yield_descending_6_10_step_4(self):
|
||||||
partition = [
|
partition = [
|
||||||
block_numbers_list
|
block_numbers_list
|
||||||
for block_numbers_list in cli.yield_blocks_numbers_lists(
|
for block_numbers_list in ethcrawler.yield_blocks_numbers_lists(
|
||||||
"6-10", block_step=4
|
"6-10", block_step=4
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
@ -52,7 +52,7 @@ class TestYieldBlockNumbersLists(unittest.TestCase):
|
||||||
def test_yield_descending_6_10_step_3(self):
|
def test_yield_descending_6_10_step_3(self):
|
||||||
partition = [
|
partition = [
|
||||||
block_numbers_list
|
block_numbers_list
|
||||||
for block_numbers_list in cli.yield_blocks_numbers_lists(
|
for block_numbers_list in ethcrawler.yield_blocks_numbers_lists(
|
||||||
"6-10", block_step=3
|
"6-10", block_step=3
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
@ -61,8 +61,8 @@ class TestYieldBlockNumbersLists(unittest.TestCase):
|
||||||
def test_yield_descending_6_10_descending_step_3(self):
|
def test_yield_descending_6_10_descending_step_3(self):
|
||||||
partition = [
|
partition = [
|
||||||
block_numbers_list
|
block_numbers_list
|
||||||
for block_numbers_list in cli.yield_blocks_numbers_lists(
|
for block_numbers_list in ethcrawler.yield_blocks_numbers_lists(
|
||||||
"6-10", cli.ProcessingOrder.DESCENDING, 3
|
"6-10", ethcrawler.ProcessingOrder.DESCENDING, 3
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
self.assertListEqual(partition, [[10, 9, 8], [7, 6]])
|
self.assertListEqual(partition, [[10, 9, 8], [7, 6]])
|
||||||
|
@ -70,8 +70,8 @@ class TestYieldBlockNumbersLists(unittest.TestCase):
|
||||||
def test_yield_descending_6_10_descending_step_10(self):
|
def test_yield_descending_6_10_descending_step_10(self):
|
||||||
partition = [
|
partition = [
|
||||||
block_numbers_list
|
block_numbers_list
|
||||||
for block_numbers_list in cli.yield_blocks_numbers_lists(
|
for block_numbers_list in ethcrawler.yield_blocks_numbers_lists(
|
||||||
"6-10", cli.ProcessingOrder.DESCENDING, 10
|
"6-10", ethcrawler.ProcessingOrder.DESCENDING, 10
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
self.assertListEqual(partition, [[10, 9, 8, 7, 6]])
|
self.assertListEqual(partition, [[10, 9, 8, 7, 6]])
|
||||||
|
@ -79,8 +79,8 @@ class TestYieldBlockNumbersLists(unittest.TestCase):
|
||||||
def test_yield_ascending_10_6_ascending_step_3(self):
|
def test_yield_ascending_10_6_ascending_step_3(self):
|
||||||
partition = [
|
partition = [
|
||||||
block_numbers_list
|
block_numbers_list
|
||||||
for block_numbers_list in cli.yield_blocks_numbers_lists(
|
for block_numbers_list in ethcrawler.yield_blocks_numbers_lists(
|
||||||
"10-6", cli.ProcessingOrder.ASCENDING, 3
|
"10-6", ethcrawler.ProcessingOrder.ASCENDING, 3
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
self.assertListEqual(partition, [[6, 7, 8], [9, 10]])
|
self.assertListEqual(partition, [[6, 7, 8], [9, 10]])
|
||||||
|
@ -88,8 +88,8 @@ class TestYieldBlockNumbersLists(unittest.TestCase):
|
||||||
def test_yield_ascending_10_6_ascending_step_10(self):
|
def test_yield_ascending_10_6_ascending_step_10(self):
|
||||||
partition = [
|
partition = [
|
||||||
block_numbers_list
|
block_numbers_list
|
||||||
for block_numbers_list in cli.yield_blocks_numbers_lists(
|
for block_numbers_list in ethcrawler.yield_blocks_numbers_lists(
|
||||||
"10-6", cli.ProcessingOrder.ASCENDING, 10
|
"10-6", ethcrawler.ProcessingOrder.ASCENDING, 10
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
self.assertListEqual(partition, [[6, 7, 8, 9, 10]])
|
self.assertListEqual(partition, [[6, 7, 8, 9, 10]])
|
||||||
|
@ -97,8 +97,8 @@ class TestYieldBlockNumbersLists(unittest.TestCase):
|
||||||
def test_yield_ascending_6_10_ascending_step_4(self):
|
def test_yield_ascending_6_10_ascending_step_4(self):
|
||||||
partition = [
|
partition = [
|
||||||
block_numbers_list
|
block_numbers_list
|
||||||
for block_numbers_list in cli.yield_blocks_numbers_lists(
|
for block_numbers_list in ethcrawler.yield_blocks_numbers_lists(
|
||||||
"6-10", cli.ProcessingOrder.ASCENDING, 4
|
"6-10", ethcrawler.ProcessingOrder.ASCENDING, 4
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
self.assertListEqual(partition, [[6, 7, 8, 9], [10]])
|
self.assertListEqual(partition, [[6, 7, 8, 9], [10]])
|
||||||
|
@ -106,8 +106,8 @@ class TestYieldBlockNumbersLists(unittest.TestCase):
|
||||||
def test_yield_ascending_6_10_ascending_step_10(self):
|
def test_yield_ascending_6_10_ascending_step_10(self):
|
||||||
partition = [
|
partition = [
|
||||||
block_numbers_list
|
block_numbers_list
|
||||||
for block_numbers_list in cli.yield_blocks_numbers_lists(
|
for block_numbers_list in ethcrawler.yield_blocks_numbers_lists(
|
||||||
"6-10", cli.ProcessingOrder.ASCENDING, 10
|
"6-10", ethcrawler.ProcessingOrder.ASCENDING, 10
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
self.assertListEqual(partition, [[6, 7, 8, 9, 10]])
|
self.assertListEqual(partition, [[6, 7, 8, 9, 10]])
|
||||||
|
|
|
@ -40,7 +40,9 @@ setup(
|
||||||
"web3",
|
"web3",
|
||||||
"boto3",
|
"boto3",
|
||||||
],
|
],
|
||||||
extras_require={"dev": ["black", "mypy", "types-requests"]},
|
extras_require={
|
||||||
|
"dev": ["black", "mypy", "types-requests", "types-python-dateutil"]
|
||||||
|
},
|
||||||
entry_points={
|
entry_points={
|
||||||
"console_scripts": [
|
"console_scripts": [
|
||||||
"ethcrawler=mooncrawl.ethcrawler:main",
|
"ethcrawler=mooncrawl.ethcrawler:main",
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useEffect, useState, useLayoutEffect, useContext } from "react";
|
import React, { useEffect, useState, useLayoutEffect } from "react";
|
||||||
import {
|
import {
|
||||||
Heading,
|
Heading,
|
||||||
Text,
|
Text,
|
||||||
|
@ -9,10 +9,9 @@ import {
|
||||||
useMediaQuery,
|
useMediaQuery,
|
||||||
UnorderedList,
|
UnorderedList,
|
||||||
ListItem,
|
ListItem,
|
||||||
|
useBreakpointValue,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import { DEFAULT_METATAGS, AWS_ASSETS_PATH } from "../../src/core/constants";
|
import { DEFAULT_METATAGS, AWS_ASSETS_PATH } from "../../src/core/constants";
|
||||||
import UIContext from "../../src/core/providers/UIProvider/context";
|
|
||||||
|
|
||||||
export async function getStaticProps() {
|
export async function getStaticProps() {
|
||||||
return {
|
return {
|
||||||
props: { metaTags: { ...DEFAULT_METATAGS } },
|
props: { metaTags: { ...DEFAULT_METATAGS } },
|
||||||
|
@ -20,14 +19,13 @@ export async function getStaticProps() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const assets = {
|
const assets = {
|
||||||
background720: `${AWS_ASSETS_PATH}/blog-background-720x405.png`,
|
background720: `${AWS_ASSETS_PATH}/product-background-720x405.png`,
|
||||||
background1920: `${AWS_ASSETS_PATH}/blog-background-720x405.png`,
|
background1920: `${AWS_ASSETS_PATH}/product-background-720x405.png`,
|
||||||
background2880: `${AWS_ASSETS_PATH}/blog-background-720x405.png`,
|
background2880: `${AWS_ASSETS_PATH}/product-background-720x405.png`,
|
||||||
background3840: `${AWS_ASSETS_PATH}/blog-background-720x405.png`,
|
background3840: `${AWS_ASSETS_PATH}/product-background-720x405.png`,
|
||||||
};
|
};
|
||||||
|
|
||||||
const Product = () => {
|
const Product = () => {
|
||||||
const ui = useContext(UIContext);
|
|
||||||
const [background, setBackground] = useState("background720");
|
const [background, setBackground] = useState("background720");
|
||||||
const [backgroundLoaded720, setBackgroundLoaded720] = useState(false);
|
const [backgroundLoaded720, setBackgroundLoaded720] = useState(false);
|
||||||
const [backgroundLoaded1920, setBackgroundLoaded1920] = useState(false);
|
const [backgroundLoaded1920, setBackgroundLoaded1920] = useState(false);
|
||||||
|
@ -47,16 +45,18 @@ const Product = () => {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
assets["background720"] = `${AWS_ASSETS_PATH}/blog-background-720x405.png`;
|
assets[
|
||||||
|
"background720"
|
||||||
|
] = `${AWS_ASSETS_PATH}/product-background-720x405.png`;
|
||||||
assets[
|
assets[
|
||||||
"background1920"
|
"background1920"
|
||||||
] = `${AWS_ASSETS_PATH}/blog-background-1920x1080.png`;
|
] = `${AWS_ASSETS_PATH}/product-background-1920x1080.png`;
|
||||||
assets[
|
assets[
|
||||||
"background2880"
|
"background2880"
|
||||||
] = `${AWS_ASSETS_PATH}/blog-background-2880x1620.png`;
|
] = `${AWS_ASSETS_PATH}/product-background-2880x1620.png`;
|
||||||
assets[
|
assets[
|
||||||
"background3840"
|
"background3840"
|
||||||
] = `${AWS_ASSETS_PATH}/blog-background-3840x2160.png`;
|
] = `${AWS_ASSETS_PATH}/product-background-3840x2160.png`;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
|
@ -82,7 +82,7 @@ const Product = () => {
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
const imageLoader720 = new Image();
|
const imageLoader720 = new Image();
|
||||||
imageLoader720.src = `${AWS_ASSETS_PATH}/blog-background-720x405.png`;
|
imageLoader720.src = `${AWS_ASSETS_PATH}/product-background-720x405.png`;
|
||||||
imageLoader720.onload = () => {
|
imageLoader720.onload = () => {
|
||||||
setBackgroundLoaded720(true);
|
setBackgroundLoaded720(true);
|
||||||
};
|
};
|
||||||
|
@ -90,7 +90,7 @@ const Product = () => {
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
const imageLoader1920 = new Image();
|
const imageLoader1920 = new Image();
|
||||||
imageLoader1920.src = `${AWS_ASSETS_PATH}/blog-background-1920x1080.png`;
|
imageLoader1920.src = `${AWS_ASSETS_PATH}/product-background-1920x1080.png`;
|
||||||
imageLoader1920.onload = () => {
|
imageLoader1920.onload = () => {
|
||||||
setBackgroundLoaded1920(true);
|
setBackgroundLoaded1920(true);
|
||||||
};
|
};
|
||||||
|
@ -98,7 +98,7 @@ const Product = () => {
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
const imageLoader2880 = new Image();
|
const imageLoader2880 = new Image();
|
||||||
imageLoader2880.src = `${AWS_ASSETS_PATH}/blog-background-2880x1620.png`;
|
imageLoader2880.src = `${AWS_ASSETS_PATH}/product-background-2880x1620.png`;
|
||||||
imageLoader2880.onload = () => {
|
imageLoader2880.onload = () => {
|
||||||
setBackgroundLoaded2880(true);
|
setBackgroundLoaded2880(true);
|
||||||
};
|
};
|
||||||
|
@ -106,13 +106,20 @@ const Product = () => {
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
const imageLoader3840 = new Image();
|
const imageLoader3840 = new Image();
|
||||||
imageLoader3840.src = `${AWS_ASSETS_PATH}/blog-background-3840x2160.png`;
|
imageLoader3840.src = `${AWS_ASSETS_PATH}/product-background-3840x2160.png`;
|
||||||
imageLoader3840.onload = () => {
|
imageLoader3840.onload = () => {
|
||||||
setBackgroundLoaded3840(true);
|
setBackgroundLoaded3840(true);
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const margin = ui.isMobileView ? "7%" : "25%";
|
const margin = useBreakpointValue({
|
||||||
|
base: "1%",
|
||||||
|
sm: "2%",
|
||||||
|
md: "3%",
|
||||||
|
lg: "15%",
|
||||||
|
xl: "20%",
|
||||||
|
"2xl": "25%",
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
|
@ -124,36 +131,63 @@ const Product = () => {
|
||||||
minH="100vh"
|
minH="100vh"
|
||||||
direction="column"
|
direction="column"
|
||||||
alignItems="center"
|
alignItems="center"
|
||||||
|
pb={24}
|
||||||
>
|
>
|
||||||
<Stack mx={margin} my={12} maxW="1700px">
|
<Stack mx={margin} my={12} maxW="1700px">
|
||||||
<Heading as="h2" size="md" w="100%" px={12} py={2} borderTopRadius="xl">
|
<Heading as="h2" size="md" w="100%" px={12} py={2} borderTopRadius="xl">
|
||||||
Vision
|
{`Why you'll love moonstream`}
|
||||||
</Heading>
|
</Heading>
|
||||||
<chakra.span pl={2} px={12} py={2}>
|
<chakra.span pl={2} px={12} py={2}>
|
||||||
<Text mb={2}>
|
<Text mb={2}>
|
||||||
Our goal is to provide a live view of the transactions taking place
|
We strive for financial inclusion. With cryptocurrencies becoming
|
||||||
on <b>every</b> public blockchain.
|
mainstream, now is the time for anyone with a computer and access to
|
||||||
|
the Internet to utilize this opportunity to make passive income.
|
||||||
|
We’re here to make it easier.
|
||||||
</Text>
|
</Text>
|
||||||
<Text mb={2}>
|
<Text mb={2}>
|
||||||
We aim to go far beyond raw transaction information, enriching our
|
Right now our source of data is Ethereum blockchain. Our goal is to
|
||||||
view with context from centralized exchanges, the news, social
|
provide a live view of the transactions taking place on every public
|
||||||
media, and smart contract analysis.
|
blockchain - from the activity of specific accounts or smart
|
||||||
|
contracts to updates about general market movements.
|
||||||
</Text>
|
</Text>
|
||||||
<Text mb={2}>
|
<Text mb={2}>
|
||||||
Data is only as good as the decisions it informs. We are building
|
This information comes from the blockchains themselves, from their
|
||||||
Moonstream to be much more than a database. We are building
|
mempools/transaction pools, and from centralized exchanges, social
|
||||||
Moonstream to be an execution engine, where anyone can set up
|
media, and the news. This forms a stream of information tailored to
|
||||||
triggers based on Moonstream events. Triggers can submit
|
your specific needs.
|
||||||
transactions to any blockchain or they can call external APIs via
|
|
||||||
webhooks.
|
|
||||||
</Text>
|
</Text>
|
||||||
<Text mb={2}>
|
<Text mb={2}>
|
||||||
Moonstream will be accessible to humans through our dashboard and
|
We’re giving you a macro view of the crypto market with direct
|
||||||
notification system.
|
access from Moonstream dashboards to execute transactions. You can
|
||||||
|
also set up programs which execute (on- or off-chain) when your
|
||||||
|
stream meets certain conditions.
|
||||||
</Text>
|
</Text>
|
||||||
<Text mb={2}>
|
<Text mb={2}>
|
||||||
Moonstream will be accessible to software through our API and
|
Moonstream is accessible through dashboard, API and webhooks.
|
||||||
webhooks.
|
</Text>
|
||||||
|
<Text mb={2}>
|
||||||
|
Moonstream’s financial inclusion goes beyond providing access to
|
||||||
|
data. All of our work is open source as we do not believe that
|
||||||
|
proprietary technologies are financially inclusive.
|
||||||
|
</Text>
|
||||||
|
<Text mb={2}>
|
||||||
|
You can read{" "}
|
||||||
|
<Link
|
||||||
|
textColor="primary.500"
|
||||||
|
isExternal
|
||||||
|
href="https://github.com/bugout-dev/moonstream"
|
||||||
|
>
|
||||||
|
our code on GitHub.
|
||||||
|
</Link>{" "}
|
||||||
|
and keep track of our progress using{" "}
|
||||||
|
<Link
|
||||||
|
textColor="primary.500"
|
||||||
|
isExternal
|
||||||
|
href="https://github.com/bugout-dev/moonstream/milestones"
|
||||||
|
>
|
||||||
|
the Moonstream milestones
|
||||||
|
</Link>
|
||||||
|
.
|
||||||
</Text>
|
</Text>
|
||||||
</chakra.span>
|
</chakra.span>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
@ -177,9 +211,9 @@ const Product = () => {
|
||||||
Moonstream users can subscribe to events from any blockchain - from
|
Moonstream users can subscribe to events from any blockchain - from
|
||||||
the activity of specific accounts or smart contracts to updates
|
the activity of specific accounts or smart contracts to updates
|
||||||
about general market movements. This information comes from the
|
about general market movements. This information comes from the
|
||||||
blockchains themselves, from their mempools/transaction pools, and
|
blockchains themselves, from their <b>mempools/transaction</b>{" "}
|
||||||
from centralized exchanges, social media, and the news. This forms a
|
pools, and from centralized exchanges, social media, and the news.
|
||||||
stream of information tailored to their specific needs.
|
This forms a stream of information tailored to their specific needs.
|
||||||
</Text>
|
</Text>
|
||||||
<Text mb={2}>
|
<Text mb={2}>
|
||||||
They can use this information to execute transactions directly from
|
They can use this information to execute transactions directly from
|
||||||
|
|
|
@ -9,6 +9,8 @@ import {
|
||||||
useMediaQuery,
|
useMediaQuery,
|
||||||
UnorderedList,
|
UnorderedList,
|
||||||
ListItem,
|
ListItem,
|
||||||
|
Box,
|
||||||
|
SimpleGrid,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import { DEFAULT_METATAGS, AWS_ASSETS_PATH } from "../../src/core/constants";
|
import { DEFAULT_METATAGS, AWS_ASSETS_PATH } from "../../src/core/constants";
|
||||||
import UIContext from "../../src/core/providers/UIProvider/context";
|
import UIContext from "../../src/core/providers/UIProvider/context";
|
||||||
|
@ -18,6 +20,7 @@ const assets = {
|
||||||
background1920: `${AWS_ASSETS_PATH}/blog-background-720x405.png`,
|
background1920: `${AWS_ASSETS_PATH}/blog-background-720x405.png`,
|
||||||
background2880: `${AWS_ASSETS_PATH}/blog-background-720x405.png`,
|
background2880: `${AWS_ASSETS_PATH}/blog-background-720x405.png`,
|
||||||
background3840: `${AWS_ASSETS_PATH}/blog-background-720x405.png`,
|
background3840: `${AWS_ASSETS_PATH}/blog-background-720x405.png`,
|
||||||
|
team: `${AWS_ASSETS_PATH}/Team-page-illustration.png`,
|
||||||
};
|
};
|
||||||
|
|
||||||
const Product = () => {
|
const Product = () => {
|
||||||
|
@ -119,36 +122,56 @@ const Product = () => {
|
||||||
alignItems="center"
|
alignItems="center"
|
||||||
w="100%"
|
w="100%"
|
||||||
>
|
>
|
||||||
<Stack mx={margin} my={6} maxW="1700px">
|
<Stack mx={margin} maxW="1700px" w="100%">
|
||||||
<Heading as="h2" size="md" w="100%" px={12} py={2} borderTopRadius="xl">
|
<SimpleGrid
|
||||||
Meet The Moonstream Team
|
px={12}
|
||||||
</Heading>
|
alignItems="start"
|
||||||
<chakra.span pl={2} px={12} py={2}>
|
columns={{ base: 1, md: 2 }}
|
||||||
<Text mb={2}>
|
// mb={24}
|
||||||
We are a distributed team of nerds with very strong expertise in
|
spacingY={{ base: 10, md: 32 }}
|
||||||
math, software engineering, machine learning, and cryptography.
|
spacingX={{ base: 10, md: 24 }}
|
||||||
Members of our team worked at Google, at OpenAI and other great
|
>
|
||||||
companies.
|
<Box>
|
||||||
</Text>
|
<Heading as="h2" size="md" w="100%" py={6} borderTopRadius="xl">
|
||||||
<Text mb={2}>
|
Meet The Moonstream Team
|
||||||
We believe that the crypto world opens opportunities for financial
|
</Heading>
|
||||||
inclusion. Meaning that people from all walks of life and financial
|
<chakra.span pl={2} py={2}>
|
||||||
situations can have a new source of income. We are passionate about
|
<Text mb={2}>
|
||||||
developing technology that helps people become active participants
|
We are a distributed team of nerds with very strong expertise in
|
||||||
in this field and take advantage of this opportunity. We’re striving
|
math, software engineering, machine learning, and cryptography.
|
||||||
to debunk harmful stereotypes and make the crypto field more
|
Members of our team worked at Google, at OpenAI and other great
|
||||||
inclusive.
|
companies.
|
||||||
</Text>
|
</Text>
|
||||||
</chakra.span>
|
<Text mb={2}>
|
||||||
|
We believe that the crypto world opens opportunities for
|
||||||
|
financial inclusion. Meaning that people from all walks of life
|
||||||
|
and financial situations can have a new source of income. We are
|
||||||
|
passionate about developing technology that helps people become
|
||||||
|
active participants in this field and take advantage of this
|
||||||
|
opportunity. We’re striving to debunk harmful stereotypes and
|
||||||
|
make the crypto field more inclusive.
|
||||||
|
</Text>
|
||||||
|
</chakra.span>
|
||||||
|
</Box>
|
||||||
|
<Box
|
||||||
|
w="full"
|
||||||
|
h="full"
|
||||||
|
py={48}
|
||||||
|
backgroundImage={`url(${assets[`team`]})`}
|
||||||
|
backgroundSize="cover"
|
||||||
|
bgPos="bottom"
|
||||||
|
bgColor="transparent"
|
||||||
|
></Box>
|
||||||
|
</SimpleGrid>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack mx={margin} my={6} maxW="1700px">
|
<Stack mx={margin} mb={6} mt={0} maxW="1700px" w="100%">
|
||||||
<Heading
|
<Heading
|
||||||
as="h2"
|
as="h2"
|
||||||
size="md"
|
size="md"
|
||||||
w="100%"
|
w="100%"
|
||||||
// bgColor="gray.200"
|
|
||||||
px={12}
|
px={12}
|
||||||
py={2}
|
pb={2}
|
||||||
|
pt={0}
|
||||||
borderTopRadius="xl"
|
borderTopRadius="xl"
|
||||||
>
|
>
|
||||||
Values that we share within our team:
|
Values that we share within our team:
|
||||||
|
@ -156,7 +179,10 @@ const Product = () => {
|
||||||
<chakra.span pl={2} px={12} py={2}>
|
<chakra.span pl={2} px={12} py={2}>
|
||||||
<UnorderedList w="75%" pl={4}>
|
<UnorderedList w="75%" pl={4}>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<b> Be bold</b>
|
<b>Be bold</b>
|
||||||
|
</ListItem>
|
||||||
|
<ListItem>
|
||||||
|
<b>Be curious</b>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<b>Don’t be an ass</b>
|
<b>Don’t be an ass</b>
|
||||||
|
@ -178,43 +204,35 @@ const Product = () => {
|
||||||
</Text>
|
</Text>
|
||||||
</chakra.span>
|
</chakra.span>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack mx={margin} mb={12} maxW="1700px">
|
<Stack mx={margin} mb={12} maxW="1700px" w="100%">
|
||||||
<Heading
|
<Heading as="h2" size="md" w="100%" px={12} py={2} borderTopRadius="xl">
|
||||||
as="h2"
|
|
||||||
size="md"
|
|
||||||
w="100%"
|
|
||||||
// bgColor="gray.200"
|
|
||||||
px={12}
|
|
||||||
py={2}
|
|
||||||
borderTopRadius="xl"
|
|
||||||
>
|
|
||||||
Our engineering team
|
Our engineering team
|
||||||
</Heading>
|
</Heading>
|
||||||
<chakra.span pl={2} px={12} py={2}>
|
<chakra.span pl={2} px={12} py={2}>
|
||||||
<UnorderedList w="75%" pl={4} spacing={2}>
|
<UnorderedList w="75%" pl={4} spacing={2}>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<b>zomglings,</b> Founder. Number theorist. Loves playing chess
|
<b>zomglings{". "}</b> Founder. Number theorist. Loves playing
|
||||||
while programming. Fan of GO, backgammon, and video games.
|
chess while programming. Fan of GO, backgammon, and video games.
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<b>kompotkot -</b>Keeper of Secrets. Likes information security
|
<b>kompotkot{". "}</b>Keeper of Secrets. Likes information
|
||||||
since childhood, loves mountains and goes hiking from time to
|
security since childhood, loves mountains and goes hiking from
|
||||||
time. Had a close call with a wild bear in a forest once.
|
time to time. Had a close call with a wild bear in a forest once.
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<b>wizarikus -</b>Wizard. Loves mountains, bicycling, and hiking.
|
<b>wizarikus{". "}</b>Wizard. Loves mountains, bicycling, and
|
||||||
A practicing Python wizard. Also likes to cook and play the guitar
|
hiking. A practicing Python wizard. Also likes to cook and play
|
||||||
in between data witchcraft.
|
the guitar in between data witchcraft.
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<b>peersky -</b>
|
<b>peersky{". "}</b>
|
||||||
{`Spectral hopper. Perceives the world as a
|
{`Spectral hopper. Perceives the world as a
|
||||||
spectrum interacting with and within the observer's mind. Loves
|
spectrum interacting with and within the observer's mind. Loves
|
||||||
to shift in time domain to spend some of it doing fire
|
to shift in time domain to spend some of it doing fire
|
||||||
performances, surfing, and connecting with nature.`}
|
performances, surfing, and connecting with nature.`}
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<b>yhtyyar -</b>
|
<b>yhtyyar{". "}</b>
|
||||||
{`Wunderkind. Interested in Math, NLP. Loves
|
{`Wunderkind. Interested in Math, NLP. Loves
|
||||||
programming language parsing and Algorithms & Data structures.
|
programming language parsing and Algorithms & Data structures.
|
||||||
Implementing his own dialect of LISP programming language for
|
Implementing his own dialect of LISP programming language for
|
||||||
|
@ -223,25 +241,25 @@ const Product = () => {
|
||||||
</UnorderedList>
|
</UnorderedList>
|
||||||
</chakra.span>
|
</chakra.span>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack mx={margin} mb={12} maxW="1700px">
|
<Stack mx={margin} mb={12} maxW="1700px" w="100%">
|
||||||
<Heading as="h2" size="md" w="100%" px={12} py={2} borderTopRadius="xl">
|
<Heading as="h2" size="md" w="100%" px={12} py={2} borderTopRadius="xl">
|
||||||
Our marketing and growth team
|
Our marketing and growth team
|
||||||
</Heading>
|
</Heading>
|
||||||
<chakra.span pl={2} px={12} py={2}>
|
<chakra.span pl={2} px={12} py={2}>
|
||||||
<UnorderedList w="75%" pl={4}>
|
<UnorderedList w="75%" pl={4}>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<b>Pahita.</b> Dreamer. An alien who pretends to be a human. So
|
<b>Pahita{". "}</b> Dreamer. An alien who pretends to be a human.
|
||||||
far so good. Loves ecstatic dance, being alone in nature and
|
So far so good. Loves ecstatic dance, being alone in nature and
|
||||||
dreaming.
|
dreaming.
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<b>In_technicolor,</b>Mediator. Loves stand-up comedy and crying
|
<b>In_technicolor{". "}</b>Mediator. Loves stand-up comedy and
|
||||||
at nights. Volunteered at a horse farm once. Portrait artist, puts
|
crying at nights. Volunteered at a horse farm once. Portrait
|
||||||
the pain in painting.
|
artist, puts the pain in painting.
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<b>Nanaland.</b>Progress and Enthusiasm. Traveled to the North
|
<b>Nanaland{". "}</b>Progress and Enthusiasm. Traveled to the
|
||||||
Korean border at the age of 19. Half German. Counseling
|
North Korean border at the age of 19. Half German. Counseling
|
||||||
psychologist who switched to tech marketing and sales.
|
psychologist who switched to tech marketing and sales.
|
||||||
</ListItem>
|
</ListItem>
|
||||||
</UnorderedList>
|
</UnorderedList>
|
||||||
|
|
|
@ -18,6 +18,11 @@ import {
|
||||||
Flex,
|
Flex,
|
||||||
IconButton,
|
IconButton,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
|
Accordion,
|
||||||
|
AccordionItem,
|
||||||
|
AccordionButton,
|
||||||
|
AccordionPanel,
|
||||||
|
AccordionIcon,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import StepProgress from "../src/components/StepProgress";
|
import StepProgress from "../src/components/StepProgress";
|
||||||
import { ArrowLeftIcon, ArrowRightIcon } from "@chakra-ui/icons";
|
import { ArrowLeftIcon, ArrowRightIcon } from "@chakra-ui/icons";
|
||||||
|
@ -31,7 +36,6 @@ import router from "next/router";
|
||||||
import { FaFilter } from "react-icons/fa";
|
import { FaFilter } from "react-icons/fa";
|
||||||
|
|
||||||
const Welcome = () => {
|
const Welcome = () => {
|
||||||
console.count("render welcome!");
|
|
||||||
const { subscriptionsCache } = useSubscriptions();
|
const { subscriptionsCache } = useSubscriptions();
|
||||||
const ui = useContext(UIContext);
|
const ui = useContext(UIContext);
|
||||||
const { mixpanel, isLoaded, MIXPANEL_PROPS } = useContext(AnalyticsContext);
|
const { mixpanel, isLoaded, MIXPANEL_PROPS } = useContext(AnalyticsContext);
|
||||||
|
@ -99,22 +103,19 @@ const Welcome = () => {
|
||||||
py={4}
|
py={4}
|
||||||
>
|
>
|
||||||
<Heading as="h4" size="md">
|
<Heading as="h4" size="md">
|
||||||
Greetings traveller!
|
Greetings traveler!
|
||||||
</Heading>
|
</Heading>
|
||||||
<Text fontWeight="semibold" pl={2}>
|
<Text fontWeight="semibold" pl={2}>
|
||||||
{" "}
|
|
||||||
We are very excited to see you onboard!
|
We are very excited to see you onboard!
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
<Text fontWeight="semibold" pl={2}>
|
<Text fontWeight="semibold" pl={2}>
|
||||||
Moonstream is a product which helps anyone participate in
|
Moonstream is a product which helps anyone participate in
|
||||||
decentralized finance. From the most sophisticated flash
|
decentralized finance.
|
||||||
arbitrageurs to people looking for yield from currency that
|
|
||||||
would otherwise lie dormant in their exchange accounts.
|
|
||||||
</Text>
|
</Text>
|
||||||
<Text fontWeight="semibold" pl={2}>
|
<Text fontWeight="semibold" pl={2}>
|
||||||
Moonstream is ment to give you critical insights needed to
|
Moonstream is meant to give you critical insights you’ll need
|
||||||
succeed in your crypto quest!
|
to succeed in your crypto quest!
|
||||||
</Text>
|
</Text>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack
|
<Stack
|
||||||
|
@ -125,38 +126,54 @@ const Welcome = () => {
|
||||||
boxShadow="xl"
|
boxShadow="xl"
|
||||||
py={4}
|
py={4}
|
||||||
>
|
>
|
||||||
<Heading as="h4" size="md">
|
<Accordion allowToggle>
|
||||||
How does Moonstream work?
|
<AccordionItem borderWidth={0}>
|
||||||
</Heading>
|
<h2>
|
||||||
<chakra.span fontWeight="semibold" pl={2}>
|
<AccordionButton borderWidth={0}>
|
||||||
<Text fontWeight="bold" display="inline">
|
<Heading as="h4" size="md">
|
||||||
We run nodes
|
How does Moonstream work?
|
||||||
</Text>{" "}
|
</Heading>
|
||||||
- Now get most precise and accurate data you can just query
|
<AccordionIcon />
|
||||||
our database. You {`don't`} need to maintain your node, and
|
</AccordionButton>
|
||||||
still have data that miners have access to!
|
</h2>
|
||||||
</chakra.span>
|
<AccordionPanel pb={4} borderWidth={0}>
|
||||||
<chakra.span fontWeight="semibold" pl={2}>
|
<Stack direction="column">
|
||||||
<Text fontWeight="bold" display="inline">
|
<chakra.span fontWeight="semibold" pl={2}>
|
||||||
We crawl data
|
<Text fontWeight="bold" display="inline">
|
||||||
</Text>{" "}
|
We run nodes
|
||||||
We analyze millions of transactions, data, smart contract code
|
</Text>{" "}
|
||||||
to link all them together
|
- Get precise and accurate data by querying our
|
||||||
</chakra.span>
|
database. You’re getting the same data miners have
|
||||||
|
access to and you don’t have to maintain your own
|
||||||
|
node.
|
||||||
|
</chakra.span>
|
||||||
|
<chakra.span fontWeight="semibold" pl={2}>
|
||||||
|
<Text fontWeight="bold" display="inline">
|
||||||
|
We crawl data
|
||||||
|
</Text>{" "}
|
||||||
|
- We analyze millions of transactions, data, and smart
|
||||||
|
contract code to link them together.
|
||||||
|
</chakra.span>
|
||||||
|
|
||||||
<chakra.span fontWeight="semibold" pl={2}>
|
<chakra.span fontWeight="semibold" pl={2}>
|
||||||
<Text fontWeight="bold" display="inline">
|
<Text fontWeight="bold" display="inline">
|
||||||
We provide data
|
We provide data
|
||||||
</Text>{" "}
|
</Text>
|
||||||
We allow you to fetch data trough the website or trough API
|
- You can fetch data through our front end or through
|
||||||
</chakra.span>
|
API.
|
||||||
|
</chakra.span>
|
||||||
|
|
||||||
<chakra.span fontWeight="semibold" pl={2}>
|
<chakra.span fontWeight="semibold" pl={2}>
|
||||||
<Text fontWeight="bold" display="inline">
|
<Text fontWeight="bold" display="inline">
|
||||||
We analyze data
|
We analyze data
|
||||||
</Text>{" "}
|
</Text>
|
||||||
We find most interesting stuff and show it to you!
|
- We find the most interesting information and
|
||||||
</chakra.span>
|
highlight it
|
||||||
|
</chakra.span>
|
||||||
|
</Stack>
|
||||||
|
</AccordionPanel>
|
||||||
|
</AccordionItem>
|
||||||
|
</Accordion>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack
|
<Stack
|
||||||
px={12}
|
px={12}
|
||||||
|
@ -166,55 +183,71 @@ const Welcome = () => {
|
||||||
boxShadow="xl"
|
boxShadow="xl"
|
||||||
py={4}
|
py={4}
|
||||||
>
|
>
|
||||||
<Heading as="h4" size="md">
|
<Accordion allowToggle>
|
||||||
UI 101?
|
<AccordionItem borderWidth={0}>
|
||||||
</Heading>
|
<h2>
|
||||||
<Text fontWeight="semibold" pl={2}>
|
<AccordionButton borderWidth={0}>
|
||||||
On the left side corner there is sidebar that you can use to
|
<Heading as="h4" size="md">
|
||||||
navigate across the website. There are following views you can
|
UI navigation basics
|
||||||
navigate to:
|
</Heading>
|
||||||
</Text>
|
<AccordionIcon />
|
||||||
<chakra.span fontWeight="semibold" pl={2}>
|
</AccordionButton>
|
||||||
<Text fontWeight="bold" display="inline">
|
</h2>
|
||||||
Subscriptions
|
<AccordionPanel pb={4} borderWidth={0}>
|
||||||
</Text>{" "}
|
<Stack dir="column">
|
||||||
- Use this screen to set up addresses you would like to
|
<Text fontWeight="semibold" pl={2}>
|
||||||
monitor to.{" "}
|
Use the sidebar on the left for navigation:
|
||||||
<i>
|
</Text>
|
||||||
NB: Without setting up subscriptions moonstream will have
|
<chakra.span fontWeight="semibold" pl={2}>
|
||||||
quite empty feel!{" "}
|
<Text fontWeight="bold" display="inline">
|
||||||
</i>{" "}
|
Subscriptions
|
||||||
No worries, we will help you to set up your subscriptions in
|
</Text>
|
||||||
the next steps!
|
Set up addresses you would like to monitor.{" "}
|
||||||
</chakra.span>
|
<i>
|
||||||
<chakra.span fontWeight="semibold" pl={2}>
|
NB: Without any subscriptions, Moonstream will feel
|
||||||
<Text fontWeight="bold" display="inline">
|
quite empty!
|
||||||
Stream
|
</i>{" "}
|
||||||
</Text>{" "}
|
No worries, we will help you set up your
|
||||||
This view is somewhat similar to a bank statement where you
|
subscriptions.
|
||||||
can define time range and see what happened in that time over
|
<i>
|
||||||
your subscriptions. In next steps we will show how you can
|
NB: Without setting up subscriptions moonstream will
|
||||||
apply filters to it!
|
have quite empty feel!{" "}
|
||||||
</chakra.span>
|
</i>{" "}
|
||||||
|
No worries, we will help you to set up your
|
||||||
|
subscriptions in the next steps!
|
||||||
|
</chakra.span>
|
||||||
|
<chakra.span fontWeight="semibold" pl={2}>
|
||||||
|
<Text fontWeight="bold" display="inline">
|
||||||
|
Stream
|
||||||
|
</Text>{" "}
|
||||||
|
This view is similar to a bank statement. You can
|
||||||
|
define a date range and see what happened with your
|
||||||
|
subscriptions during that time. You can also apply
|
||||||
|
filters to it.
|
||||||
|
</chakra.span>
|
||||||
|
|
||||||
<chakra.span fontWeight="semibold" pl={2}>
|
<chakra.span fontWeight="semibold" pl={2}>
|
||||||
<Text fontWeight="bold" display="inline">
|
<Text fontWeight="bold" display="inline">
|
||||||
Stream Entry
|
Stream Entry
|
||||||
</Text>{" "}
|
</Text>{" "}
|
||||||
You can see detailed view of stream cards with very specific
|
- See a detailed view of stream cards with specific
|
||||||
and essential data, like methods called in smart contracts
|
and essential data, like methods called in smart
|
||||||
etc!!
|
contracts etc
|
||||||
</chakra.span>
|
</chakra.span>
|
||||||
|
|
||||||
<chakra.span fontWeight="semibold" pl={2}>
|
<chakra.span fontWeight="semibold" pl={2}>
|
||||||
<Text fontWeight="bold" display="inline">
|
<Text fontWeight="bold" display="inline">
|
||||||
Analytics
|
Analytics
|
||||||
</Text>{" "}
|
</Text>{" "}
|
||||||
This section is under construction yet. Soon you will be able
|
- This section is under construction. Soon you will be
|
||||||
to create your dashboard with data of your interest. We will
|
able to create dashboards there. Right now you can
|
||||||
really appretiate if you visit that section, and fill up form
|
fill out a form to tell us what analytical tools you’d
|
||||||
describing what analytical tools you would love to see there!
|
want to see. We’d really appreciate that :)
|
||||||
</chakra.span>
|
</chakra.span>
|
||||||
|
</Stack>
|
||||||
|
</AccordionPanel>
|
||||||
|
</AccordionItem>
|
||||||
|
</Accordion>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
<Stack
|
<Stack
|
||||||
|
@ -226,25 +259,32 @@ const Welcome = () => {
|
||||||
py={4}
|
py={4}
|
||||||
>
|
>
|
||||||
<Heading as="h4" size="md">
|
<Heading as="h4" size="md">
|
||||||
Tell us more about your needs?
|
Tell us more about your needs
|
||||||
</Heading>
|
</Heading>
|
||||||
<Text fontWeight="semibold" pl={2}>
|
<Text fontWeight="semibold" pl={2}>
|
||||||
In order to fetch best possible experience, we would like to
|
In order to create the best possible experience, we would love
|
||||||
know some details about you
|
to find out some more about you.
|
||||||
</Text>
|
</Text>
|
||||||
<Text fontWeight="semibold" pl={2}>
|
<Text fontWeight="semibold" pl={2}>
|
||||||
Please tell us what profile describes you best?{" "}
|
Please tell us what profile describes you best.{" "}
|
||||||
<i>
|
<i>
|
||||||
This is purely analytical data, you can change it anytime
|
This is purely analytical data, you can change it anytime
|
||||||
later
|
later.
|
||||||
</i>
|
</i>
|
||||||
</Text>
|
</Text>
|
||||||
<RadioGroup
|
<RadioGroup
|
||||||
|
position="relative"
|
||||||
onChange={setProfile}
|
onChange={setProfile}
|
||||||
value={profile}
|
value={profile}
|
||||||
fontWeight="bold"
|
// fontWeight="bold"
|
||||||
|
colorScheme="secondary"
|
||||||
|
// py={0}
|
||||||
|
// my={0}
|
||||||
>
|
>
|
||||||
<Stack direction="row" justifyContent="space-evenly">
|
<Stack
|
||||||
|
direction={["column", "row", null]}
|
||||||
|
justifyContent="space-evenly"
|
||||||
|
>
|
||||||
<Radio value="trader">I am trading crypto currency</Radio>
|
<Radio value="trader">I am trading crypto currency</Radio>
|
||||||
<Radio value="fund">I represent investment fund</Radio>
|
<Radio value="fund">I represent investment fund</Radio>
|
||||||
<Radio value="developer">I am developer</Radio>
|
<Radio value="developer">I am developer</Radio>
|
||||||
|
@ -270,24 +310,26 @@ const Welcome = () => {
|
||||||
Subscriptions
|
Subscriptions
|
||||||
</Heading>
|
</Heading>
|
||||||
<chakra.span fontWeight="semibold" pl={2}>
|
<chakra.span fontWeight="semibold" pl={2}>
|
||||||
Subscriptions is essential tool of Moonstream. We gather data
|
Subscriptions are an essential tool of Moonstream. We gather
|
||||||
for you based on addresses you have subscribed for.
|
data for you based on addresses you have subscribed to.
|
||||||
<br />
|
<br />
|
||||||
Subscribe to any addres which you are interested in and they
|
Subscribe to any address you are interested in and it will
|
||||||
will become part of your stream!
|
become part of your stream.
|
||||||
|
<br />
|
||||||
|
Name of subscription (you can change it later).
|
||||||
<UnorderedList>
|
<UnorderedList>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
Color - you can define color to easily identify this
|
Color - you can set colors to easily identify a
|
||||||
subscription in your stream
|
subscription in your stream
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem>Address - thing you subscribe to</ListItem>
|
<ListItem>Address - the address you subscribe to</ListItem>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
Label - Its good idea to use human readible name that
|
Label - we recommend using a human-readable name that
|
||||||
represents address
|
represents the subscription
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
Source - In Alpha we support only Ethereum blockchain,
|
Source - In Alpha we’re only supporting Ethereum
|
||||||
more sources are coming soon!
|
blockchain, but more sources are coming soon!
|
||||||
</ListItem>
|
</ListItem>
|
||||||
</UnorderedList>
|
</UnorderedList>
|
||||||
</chakra.span>
|
</chakra.span>
|
||||||
|
@ -342,35 +384,32 @@ const Welcome = () => {
|
||||||
<chakra.span fontWeight="semibold" pl={2}>
|
<chakra.span fontWeight="semibold" pl={2}>
|
||||||
We are almost done!
|
We are almost done!
|
||||||
<br />
|
<br />
|
||||||
{`Stream is where you can read data you've subscribed for. Here
|
{`Stream is where you can read data you've subscribed to. There are different cards for different subscription types.`}
|
||||||
you have different cards for different subscription types.`}
|
|
||||||
<br />
|
<br />
|
||||||
If card has some extra details - there will be orange button
|
If the card has some extra details, there will be an orange
|
||||||
on right hand side inviting you to see more!
|
button on the right hand side inviting you to see more!
|
||||||
<br />
|
<br />
|
||||||
Below is typical card for ethereum blockchain event. Useful
|
Below is a typical card for an Ethereum blockchain event.
|
||||||
information right on the card:
|
Useful information right on the card:
|
||||||
<UnorderedList py={2}>
|
<UnorderedList py={2}>
|
||||||
<ListItem>Hash - unique ID of the event </ListItem>
|
<ListItem>Hash - Unique ID of the event</ListItem>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
From - sender address. If it is one of your subscription
|
From - Sender address. If it is one of your subscription
|
||||||
addresses - will appear in color and with label{" "}
|
addresses, it will appear in color with a label
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
To - receiver address. If it is one of your subscription
|
To - Receiver address. If it is one of your subscription
|
||||||
addresses - will appear in color and with label{" "}
|
addresses, it will appear in color with a label
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
Nonce - Counter how many transactions address has sent. It
|
Nonce - Counter how many transaction addresses have been
|
||||||
also determines sequence of transaction!{" "}
|
sent. It also determines the sequence of transactions!
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
Gas Price - this is how much ether is being paid per gas
|
Gas Price - This is how much ether is being paid per gas
|
||||||
unit
|
unit
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem>
|
<ListItem>Gas - Amount of gas this event consumes</ListItem>
|
||||||
Gas - Ammount of gas this event consumes
|
|
||||||
</ListItem>
|
|
||||||
</UnorderedList>
|
</UnorderedList>
|
||||||
</chakra.span>
|
</chakra.span>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
@ -402,6 +441,7 @@ const Welcome = () => {
|
||||||
<StreamEntry
|
<StreamEntry
|
||||||
mt={20}
|
mt={20}
|
||||||
entry={{
|
entry={{
|
||||||
|
event_type: "ethereum_blockchain",
|
||||||
from_address: "this is address from",
|
from_address: "this is address from",
|
||||||
to_address: "this is to address",
|
to_address: "this is to address",
|
||||||
hash: "this is hash",
|
hash: "this is hash",
|
||||||
|
@ -422,9 +462,10 @@ const Welcome = () => {
|
||||||
Applying filters
|
Applying filters
|
||||||
</Heading>
|
</Heading>
|
||||||
<chakra.span fontWeight="semibold" pl={2}>
|
<chakra.span fontWeight="semibold" pl={2}>
|
||||||
You can apply various filters by clicking filter menu button
|
You can apply various filters by clicking the filter menu
|
||||||
|
button.
|
||||||
<br />
|
<br />
|
||||||
{`Right now you can use it to select address from and to, we are adding more complex queries soon, stay tuna! `}
|
{`Right now you can use it to select addresses from and to, and we are adding more complex queries soon — stay tuned!`}
|
||||||
<br />
|
<br />
|
||||||
</chakra.span>
|
</chakra.span>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
@ -444,20 +485,30 @@ const Welcome = () => {
|
||||||
scrollRef?.current?.scrollIntoView();
|
scrollRef?.current?.scrollIntoView();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Previous
|
Go back
|
||||||
</Button>
|
</Button>
|
||||||
<Spacer />
|
<Spacer />
|
||||||
<Button
|
<Button
|
||||||
colorScheme="secondary"
|
colorScheme={
|
||||||
variant="solid"
|
ui.onboardingStep < ui.onboardingSteps.length - 1
|
||||||
rightIcon={<ArrowRightIcon />}
|
? `secondary`
|
||||||
// hidden={!(ui.onboardingStep < ui.onboardingSteps.length - 1)}
|
: `suggested`
|
||||||
// disabled={!(ui.onboardingStep < ui.onboardingSteps.length - 1)}
|
}
|
||||||
|
variant={
|
||||||
|
ui.onboardingStep < ui.onboardingSteps.length - 1
|
||||||
|
? `solid`
|
||||||
|
: `outline`
|
||||||
|
}
|
||||||
|
rightIcon={
|
||||||
|
ui.onboardingStep < ui.onboardingSteps.length - 1 && (
|
||||||
|
<ArrowRightIcon />
|
||||||
|
)
|
||||||
|
}
|
||||||
onClick={() => handleNextClick()}
|
onClick={() => handleNextClick()}
|
||||||
>
|
>
|
||||||
{ui.onboardingStep < ui.onboardingSteps.length - 1
|
{ui.onboardingStep < ui.onboardingSteps.length - 1
|
||||||
? `Next`
|
? `Next`
|
||||||
: `Finish `}
|
: `Finish and move to stream`}
|
||||||
</Button>
|
</Button>
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Flex, Text, Link } from "@chakra-ui/react";
|
import { Flex, Text, Link, Heading } from "@chakra-ui/react";
|
||||||
import CustomIcon from "../components/CustomIcon";
|
import CustomIcon from "../components/CustomIcon";
|
||||||
|
import RouterLink from "next/link";
|
||||||
|
|
||||||
const ICONS = [
|
const ICONS = [
|
||||||
{
|
{
|
||||||
|
@ -22,6 +23,11 @@ const SITEMAP_FLEX_PROPS = {
|
||||||
mr: 12,
|
mr: 12,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const LINKS_SIZES = {
|
||||||
|
fontWeight: "300",
|
||||||
|
fontSize: "lg",
|
||||||
|
};
|
||||||
|
|
||||||
const Footer = () => (
|
const Footer = () => (
|
||||||
<Flex
|
<Flex
|
||||||
bg="brand.200"
|
bg="brand.200"
|
||||||
|
@ -42,31 +48,28 @@ const Footer = () => (
|
||||||
maxW="40rem"
|
maxW="40rem"
|
||||||
>
|
>
|
||||||
<Flex {...SITEMAP_FLEX_PROPS}>
|
<Flex {...SITEMAP_FLEX_PROPS}>
|
||||||
{/* <Heading pb={8} size="md">
|
<Heading pb={8} size="md">
|
||||||
About
|
About
|
||||||
</Heading> */}
|
</Heading>{" "}
|
||||||
{/* <RouterLink passHref href="/team">
|
<RouterLink passHref href="/team">
|
||||||
<Link {...LINKS_SIZES}>Team</Link>
|
<Link {...LINKS_SIZES}>Team</Link>
|
||||||
</RouterLink> */}
|
|
||||||
{/* <RouterLink passHref href="/events">
|
|
||||||
<Link {...LINKS_SIZES}>Events</Link>
|
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
<RouterLink passHref href="http://blog.bugout.dev">
|
<RouterLink passHref href="/product">
|
||||||
<Link {...LINKS_SIZES}>Blog</Link>
|
<Link {...LINKS_SIZES}>Product</Link>
|
||||||
</RouterLink> */}
|
</RouterLink>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
<Flex {...SITEMAP_FLEX_PROPS}>
|
<Flex {...SITEMAP_FLEX_PROPS}>
|
||||||
{/* <Heading pb={8} size="md">
|
<Heading pb={8} size="md">
|
||||||
Legal
|
News
|
||||||
</Heading>
|
</Heading>
|
||||||
<RouterLink href="/tos" passHref>
|
<RouterLink passHref href="http://blog.moonstream.to">
|
||||||
<Link {...LINKS_SIZES}>Terms of service</Link>
|
<Link {...LINKS_SIZES}>Blog</Link>
|
||||||
</RouterLink> */}
|
</RouterLink>
|
||||||
{/* <RouterLink passHref href="/privacy-policy">
|
{/* <RouterLink passHref href="/privacy-policy">
|
||||||
<Link {...LINKS_SIZES}>Privacy policy</Link>
|
<Link {...LINKS_SIZES}>Privacy policy</Link>
|
||||||
</RouterLink> */}
|
</RouterLink> */}
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
{/* <Flex {...SITEMAP_FLEX_PROPS}>
|
{/* <Flex {...SITEMAP_FLEX_PROPS}>
|
||||||
<Heading pb={8} size="md">
|
<Heading pb={8} size="md">
|
||||||
Product
|
Product
|
||||||
|
@ -94,7 +97,7 @@ const Footer = () => (
|
||||||
fontSize="xl"
|
fontSize="xl"
|
||||||
fontWeight="500"
|
fontWeight="500"
|
||||||
>
|
>
|
||||||
Stay in touch{` `}
|
All the crypto data you care about{` `}
|
||||||
<span role="img" aria-label="heart">
|
<span role="img" aria-label="heart">
|
||||||
💙
|
💙
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -129,7 +129,6 @@ const NewSubscription = ({ isFreeOption, onClose }) => {
|
||||||
</Text>{" "}
|
</Text>{" "}
|
||||||
<IconButton
|
<IconButton
|
||||||
size="md"
|
size="md"
|
||||||
// colorScheme="primary"
|
|
||||||
color={"white.100"}
|
color={"white.100"}
|
||||||
_hover={{ bgColor: { color } }}
|
_hover={{ bgColor: { color } }}
|
||||||
bgColor={color}
|
bgColor={color}
|
||||||
|
@ -148,10 +147,7 @@ const NewSubscription = ({ isFreeOption, onClose }) => {
|
||||||
></Input>
|
></Input>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
<GithubPicker
|
<GithubPicker onChangeComplete={handleChangeColorComplete} />
|
||||||
// color={this.state.background}
|
|
||||||
onChangeComplete={handleChangeColorComplete}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormErrorMessage color="unsafe.400" pl="1">
|
<FormErrorMessage color="unsafe.400" pl="1">
|
||||||
{errors.color && errors.color.message}
|
{errors.color && errors.color.message}
|
||||||
|
|
|
@ -73,7 +73,7 @@ const _NewSubscription = ({ isFreeOption, onClose, setIsLoading }) => {
|
||||||
my={2}
|
my={2}
|
||||||
type="text"
|
type="text"
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
placeholder="Meaningful name of your subscription"
|
placeholder="Name of subscription (you can change it later)"
|
||||||
name="label"
|
name="label"
|
||||||
ref={register({ required: "label is required!" })}
|
ref={register({ required: "label is required!" })}
|
||||||
></Input>
|
></Input>
|
||||||
|
|
Ładowanie…
Reference in New Issue