From db9b6118c2e355dbe01220f7d6858999535f761a Mon Sep 17 00:00:00 2001 From: lAmeR <42315864+lAmeR1@users.noreply.github.com> Date: Thu, 23 Mar 2023 00:00:45 +0100 Subject: [PATCH] only socket server needed here --- .github/workflows/docker-image.yml | 2 +- endpoints/get_address_transactions.py | 148 ----------- endpoints/get_balance.py | 45 ---- endpoints/get_blockdag.py | 18 +- endpoints/get_blockreward.py | 36 --- endpoints/get_blocks.py | 212 --------------- endpoints/get_circulating_supply.py | 18 +- endpoints/get_halving.py | 54 ---- endpoints/get_hashrate.py | 84 ------ endpoints/get_health.py | 57 ----- endpoints/get_kaspad_info.py | 25 -- endpoints/get_marketcap.py | 32 --- endpoints/get_network.py | 24 +- endpoints/get_price.py | 31 --- endpoints/get_transactions.py | 241 ------------------ endpoints/get_utxos.py | 49 ---- endpoints/get_virtual_chain_blue_score.py | 10 +- endpoints/get_vspc.py | 40 --- endpoints/kaspad_requests/__init__.py | 0 .../submit_transaction_request.py | 118 --------- main.py | 22 +- models/Block.py | 29 --- models/Transaction.py | 42 --- models/TxAddrMapping.py | 12 - models/Variable.py | 9 - models/__init__.py | 0 26 files changed, 9 insertions(+), 1349 deletions(-) delete mode 100644 endpoints/get_address_transactions.py delete mode 100644 endpoints/get_balance.py delete mode 100644 endpoints/get_blockreward.py delete mode 100644 endpoints/get_blocks.py delete mode 100644 endpoints/get_halving.py delete mode 100644 endpoints/get_hashrate.py delete mode 100644 endpoints/get_health.py delete mode 100644 endpoints/get_kaspad_info.py delete mode 100644 endpoints/get_marketcap.py delete mode 100644 endpoints/get_price.py delete mode 100644 endpoints/get_transactions.py delete mode 100644 endpoints/get_utxos.py delete mode 100644 endpoints/get_vspc.py delete mode 100644 endpoints/kaspad_requests/__init__.py delete mode 100644 endpoints/kaspad_requests/submit_transaction_request.py delete mode 100644 models/Block.py delete mode 100644 models/Transaction.py delete mode 100644 models/TxAddrMapping.py delete mode 100644 models/Variable.py delete mode 100644 models/__init__.py diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 322e303..61c7395 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -25,7 +25,7 @@ jobs: with: context: . push: true - tags: supertypo/kaspa-rest-server:${{github.ref_name}}, supertypo/kaspa-rest-server:latest + tags: lamer1/kaspa-socket-server:${{github.ref_name}}, lamer1/kaspa-socket-server:latest file: ./docker/Dockerfile build-args: | version=${{github.ref_name}} diff --git a/endpoints/get_address_transactions.py b/endpoints/get_address_transactions.py deleted file mode 100644 index 2a7089a..0000000 --- a/endpoints/get_address_transactions.py +++ /dev/null @@ -1,148 +0,0 @@ -# encoding: utf-8 -from enum import Enum -from typing import List - -from fastapi import Path, Query -from pydantic import BaseModel -from sqlalchemy import text, func -from sqlalchemy.future import select -from endpoints.get_transactions import search_for_transactions, TxSearch, TxModel - -from dbsession import async_session -from server import app - -from models.TxAddrMapping import TxAddrMapping - -DESC_RESOLVE_PARAM = "Use this parameter if you want to fetch the TransactionInput previous outpoint details." \ - " Light fetches only the address and amount. Full fetches the whole TransactionOutput and " \ - "adds it into each TxInput." - - -class TransactionsReceivedAndSpent(BaseModel): - tx_received: str - tx_spent: str | None - # received_amount: int = 38240000000 - - -class TransactionForAddressResponse(BaseModel): - transactions: List[TransactionsReceivedAndSpent] - - -class TransactionCount(BaseModel): - total: int - - -class PreviousOutpointLookupMode(str, Enum): - no = "no" - light = "light" - full = "full" - - -@app.get("/addresses/{kaspaAddress}/transactions", - response_model=TransactionForAddressResponse, - response_model_exclude_unset=True, - tags=["Kaspa addresses"], - deprecated=True) -async def get_transactions_for_address( - kaspaAddress: str = Path( - description="Kaspa address as string e.g. " - "kaspa:pzhh76qc82wzduvsrd9xh4zde9qhp0xc8rl7qu2mvl2e42uvdqt75zrcgpm00", - regex="^kaspa\:[a-z0-9]{61,63}$")): - """ - Get all transactions for a given address from database - """ - # SELECT transactions_outputs.transaction_id, transactions_inputs.transaction_id as inp_transaction FROM transactions_outputs - # - # LEFT JOIN transactions_inputs ON transactions_inputs.previous_outpoint_hash = transactions_outputs.transaction_id AND transactions_inputs.previous_outpoint_index::int = transactions_outputs.index - # - # WHERE "script_public_key_address" = 'kaspa:qp7d7rzrj34s2k3qlxmguuerfh2qmjafc399lj6606fc7s69l84h7mrj49hu6' - # - # ORDER by transactions_outputs.transaction_id - async with async_session() as session: - resp = await session.execute(text(f""" - SELECT transactions_outputs.transaction_id, transactions_outputs.index, transactions_inputs.transaction_id as inp_transaction, - transactions.block_time, transactions.transaction_id - - FROM transactions - LEFT JOIN transactions_outputs ON transactions.transaction_id = transactions_outputs.transaction_id - LEFT JOIN transactions_inputs ON transactions_inputs.previous_outpoint_hash = transactions.transaction_id AND transactions_inputs.previous_outpoint_index::int = transactions_outputs.index - WHERE "script_public_key_address" = :kaspaAddress - ORDER by transactions.block_time DESC - LIMIT 500"""), - {'kaspaAddress': kaspaAddress}) - - resp = resp.all() - - # build response - tx_list = [] - for x in resp: - tx_list.append({"tx_received": x[0], - "tx_spent": x[2]}) - return { - "transactions": tx_list - } - - -@app.get("/addresses/{kaspaAddress}/full-transactions", - response_model=List[TxModel], - response_model_exclude_unset=True, - tags=["Kaspa addresses"]) -async def get_full_transactions_for_address( - kaspaAddress: str = Path( - description="Kaspa address as string e.g. " - "kaspa:pzhh76qc82wzduvsrd9xh4zde9qhp0xc8rl7qu2mvl2e42uvdqt75zrcgpm00", - regex="^kaspa\:[a-z0-9]{61,63}$"), - limit: int = Query( - description="The number of records to get", - ge=1, - le=500, - default=50), - offset: int = Query( - description="The offset from which to get records", - ge=0, - default=0), - fields: str = "", - resolve_previous_outpoints: PreviousOutpointLookupMode = - Query(default="no", - description=DESC_RESOLVE_PARAM)): - """ - Get all transactions for a given address from database. - And then get their related full transaction data - """ - - async with async_session() as s: - # Doing it this way as opposed to adding it directly in the IN clause - # so I can re-use the same result in tx_list, TxInput and TxOutput - tx_within_limit_offset = await s.execute(select(TxAddrMapping.transaction_id) - .filter(TxAddrMapping.address == kaspaAddress) - .limit(limit) - .offset(offset) - .order_by(TxAddrMapping.block_time.desc()) - ) - - tx_ids_in_page = [x[0] for x in tx_within_limit_offset.all()] - - return await search_for_transactions(TxSearch(transactionIds=tx_ids_in_page), - fields, - resolve_previous_outpoints) - - -@app.get("/addresses/{kaspaAddress}/transactions-count", - response_model=TransactionCount, - tags=["Kaspa addresses"]) -async def get_transaction_count_for_address( - kaspaAddress: str = Path( - description="Kaspa address as string e.g. " - "kaspa:pzhh76qc82wzduvsrd9xh4zde9qhp0xc8rl7qu2mvl2e42uvdqt75zrcgpm00", - regex="^kaspa\:[a-z0-9]{61,63}$") -): - """ - Count the number of transactions associated with this address - """ - - async with async_session() as s: - count_query = select(func.count()).filter(TxAddrMapping.address == kaspaAddress) - - tx_count = await s.execute(count_query) - - return TransactionCount(total=tx_count.scalar()) diff --git a/endpoints/get_balance.py b/endpoints/get_balance.py deleted file mode 100644 index 6ccd08a..0000000 --- a/endpoints/get_balance.py +++ /dev/null @@ -1,45 +0,0 @@ -# encoding: utf-8 - -from fastapi import Path, HTTPException -from pydantic import BaseModel - -from server import app, kaspad_client - - -class BalanceResponse(BaseModel): - address: str = "kaspa:pzhh76qc82wzduvsrd9xh4zde9qhp0xc8rl7qu2mvl2e42uvdqt75zrcgpm00" - balance: int = 38240000000 - - -@app.get("/addresses/{kaspaAddress}/balance", response_model=BalanceResponse, tags=["Kaspa addresses"]) -async def get_balance_from_kaspa_address( - kaspaAddress: str = Path( - description="Kaspa address as string e.g. kaspa:pzhh76qc82wzduvsrd9xh4zde9qhp0xc8rl7qu2mvl2e42uvdqt75zrcgpm00", - regex="^kaspa\:[a-z0-9]{61,63}$")): - """ - Get balance for a given kaspa address - """ - resp = await kaspad_client.request("getBalanceByAddressRequest", - params={ - "address": kaspaAddress - }) - - try: - resp = resp["getBalanceByAddressResponse"] - except KeyError: - if "getUtxosByAddressesResponse" in resp and "error" in resp["getUtxosByAddressesResponse"]: - raise HTTPException(status_code=400, detail=resp["getUtxosByAddressesResponse"]["error"]) - else: - raise - - try: - balance = int(resp["balance"]) - - # return 0 if address is ok, but no utxos there - except KeyError: - balance = 0 - - return { - "address": kaspaAddress, - "balance": balance - } diff --git a/endpoints/get_blockdag.py b/endpoints/get_blockdag.py index ccf4ef2..f428c9c 100644 --- a/endpoints/get_blockdag.py +++ b/endpoints/get_blockdag.py @@ -1,24 +1,8 @@ # encoding: utf-8 -from typing import List -from pydantic import BaseModel +from server import kaspad_client -from server import app, kaspad_client - -class BlockdagResponse(BaseModel): - networkName: str = "kaspa-mainnet" - blockCount: str = "260890" - headerCount: str = "2131312" - tipHashes: List[str] = ["78273854a739e3e379dfd34a262bbe922400d8e360e30e3f31228519a334350a"] - difficulty: float = 3870677677777.2 - pastMedianTime: str = "1656455670700" - virtualParentHashes: List[str] = ["78273854a739e3e379dfd34a262bbe922400d8e360e30e3f31228519a334350a"] - pruningPointHash: str = "5d32a9403273a34b6551b84340a1459ddde2ae6ba59a47987a6374340ba41d5d", - virtualDaaScore: str = "19989141" - - -@app.get("/info/blockdag", response_model=BlockdagResponse, tags=["Kaspa network info"]) async def get_blockdag(): """ Get some global Kaspa BlockDAG information diff --git a/endpoints/get_blockreward.py b/endpoints/get_blockreward.py deleted file mode 100644 index 34225f8..0000000 --- a/endpoints/get_blockreward.py +++ /dev/null @@ -1,36 +0,0 @@ -# encoding: utf-8 - -from pydantic import BaseModel - -from helper.deflationary_table import DEFLATIONARY_TABLE -from server import app, kaspad_client - - -class BlockRewardResponse(BaseModel): - blockreward: float = 12000132 - - -@app.get("/info/blockreward", response_model=BlockRewardResponse | str, tags=["Kaspa network info"]) -async def get_blockreward(stringOnly: bool = False): - """ - Returns the current blockreward in KAS/block - """ - resp = await kaspad_client.request("getBlockDagInfoRequest") - daa_score = int(resp["getBlockDagInfoResponse"]["virtualDaaScore"]) - - reward = 0 - - for to_break_score in sorted(DEFLATIONARY_TABLE): - reward = DEFLATIONARY_TABLE[to_break_score] - if daa_score < to_break_score: - break - - if not stringOnly: - return { - "blockreward": reward - } - - else: - return f"{reward:.2f}" - - diff --git a/endpoints/get_blocks.py b/endpoints/get_blocks.py deleted file mode 100644 index f083d47..0000000 --- a/endpoints/get_blocks.py +++ /dev/null @@ -1,212 +0,0 @@ -# encoding: utf-8 -from typing import List - -from fastapi import Query, Path, HTTPException -from fastapi import Response -from pydantic import BaseModel -from sqlalchemy import select - -from dbsession import async_session -from models.Block import Block -from models.Transaction import Transaction, TransactionOutput, TransactionInput -from server import app, kaspad_client - - -class VerboseDataModel(BaseModel): - hash: str = "18c7afdf8f447ca06adb8b4946dc45f5feb1188c7d177da6094dfbc760eca699" - difficulty: float = 4102204523252.94, - selectedParentHash: str = "580f65c8da9d436480817f6bd7c13eecd9223b37f0d34ae42fb17e1e9fda397e" - transactionIds: List[str] = ["533f8314bf772259fe517f53507a79ebe61c8c6a11748d93a0835551233b3311"] - blueScore: str = "18483232" - childrenHashes: List[str] = ["2fda0dad4ec879b4ad02ebb68c757955cab305558998129a7de111ab852e7dcb", - "9a822351cd293a653f6721afec1646bd1690da7124b5fbe87001711406010604" - ] - mergeSetBluesHashes: List[str] = ["580f65c8da9d436480817f6bd7c13eecd9223b37f0d34ae42fb17e1e9fda397e"] - mergeSetRedsHashes: List[str] = ["580f65c8da9d436480817f6bd7c13eecd9223b37f0d34ae42fb17e1e9fda397e"] - isChainBlock: bool = False - - -class ParentHashModel(BaseModel): - parentHashes: List[str] = ["580f65c8da9d436480817f6bd7c13eecd9223b37f0d34ae42fb17e1e9fda397e"] - - -class BlockHeader(BaseModel): - version: int = 1 - hashMerkleRoot: str = "e6641454e16cff4f232b899564eeaa6e480b66069d87bee6a2b2476e63fcd887" - acceptedIdMerkleRoot: str = "9bab45b027a0b2b47135b6f6f866e5e4040fc1fdf2fe56eb0c90a603ce86092b" - utxoCommitment: str = "236d5f9ffd19b317a97693322c3e2ae11a44b5df803d71f1ccf6c2393bc6143c" - timestamp: str = "1656450648874" - bits: int = 455233226 - nonce: str = "14797571275553019490" - daaScore: str = "19984482" - blueWork: str = "2d1b3f04f8a0dcd31" - parents: List[ParentHashModel] - blueScore: str = "18483232" - pruningPoint: str = "5d32a9403273a34b6551b84340a1459ddde2ae6ba59a47987a6374340ba41d5d" - - -class BlockModel(BaseModel): - header: BlockHeader - transactions: list | None - verboseData: VerboseDataModel - - -class BlockResponse(BaseModel): - blockHashes: List[str] = ["44edf9bfd32aa154bfad64485882f184372b64bd60565ba121b42fc3cb1238f3", - "18c7afdf8f447ca06adb8b4946dc45f5feb1188c7d177da6094dfbc760eca699", - "9a822351cd293a653f6721afec1646bd1690da7124b5fbe87001711406010604", - "2fda0dad4ec879b4ad02ebb68c757955cab305558998129a7de111ab852e7dcb"] - blocks: List[BlockModel] | None - - -@app.get("/blocks/{blockId}", response_model=BlockModel, tags=["Kaspa blocks"]) -async def get_block(response: Response, - blockId: str = Path(regex="[a-f0-9]{64}")): - """ - Get block information for a given block id - """ - resp = await kaspad_client.request("getBlockRequest", - params={ - "hash": blockId, - "includeTransactions": True - }) - requested_block = None - - if "block" in resp["getBlockResponse"]: - # We found the block in kaspad. Just use it - requested_block = resp["getBlockResponse"]["block"] - else: - # Didn't find the block in kaspad. Try getting it from the DB - response.headers["X-Data-Source"] = "Database" - requested_block = await get_block_from_db(blockId) - - if not requested_block: - # Still did not get the block - raise HTTPException(status_code=404, detail="Block not found") - - # We found the block, now we guarantee it contains the transactions - # It's possible that the block from kaspad does not contain transactions - if 'transactions' not in requested_block or not requested_block['transactions']: - requested_block['transactions'] = await get_block_transactions(blockId) - - return requested_block - -@app.get("/blocks", response_model=BlockResponse, tags=["Kaspa blocks"]) -async def get_blocks(lowHash: str = Query(regex="[a-f0-9]{64}"), - includeBlocks: bool = False, - includeTransactions: bool = False): - """ - Lists block beginning from a low hash (block id). Note that this function is running on a kaspad and not returning - data from database. - """ - resp = await kaspad_client.request("getBlocksRequest", - params={ - "lowHash": lowHash, - "includeBlocks": includeBlocks, - "includeTransactions": includeTransactions - }) - - return resp["getBlocksResponse"] - -""" -Get the block from the database -""" -async def get_block_from_db(blockId): - async with async_session() as s: - requested_block = await s.execute(select(Block) - .where(Block.hash == blockId).limit(1)) - - try: - requested_block = requested_block.first()[0] # type: Block - except TypeError: - raise HTTPException(status_code=404, detail="Block not found") - - if requested_block: - return { - "header": { - "version": requested_block.version, - "hashMerkleRoot": requested_block.hash_merkle_root, - "acceptedIdMerkleRoot": requested_block.accepted_id_merkle_root, - "utxoCommitment": requested_block.utxo_commitment, - "timestamp": round(requested_block.timestamp.timestamp() * 1000), - "bits": requested_block.bits, - "nonce": requested_block.nonce, - "daaScore": requested_block.daa_score, - "blueWork": requested_block.blue_work, - "parents": [{"parentHashes": requested_block.parents}], - "blueScore": requested_block.blue_score, - "pruningPoint": requested_block.pruning_point - }, - "transactions": None, # This will be filled later - "verboseData": { - "hash": requested_block.hash, - "difficulty": requested_block.difficulty, - "selectedParentHash": requested_block.selected_parent_hash, - "transactionIds": [], - "blueScore": requested_block.blue_score, - "childrenHashes": [], - "mergeSetBluesHashes": requested_block.merge_set_blues_hashes, - "mergeSetRedsHashes": requested_block.merge_set_reds_hashes, - "isChainBlock": requested_block.is_chain_block - } - } - return None - -""" -Get the transactions associated with a block -""" -async def get_block_transactions(blockId): - # create tx data - tx_list = [] - - async with async_session() as s: - transactions = await s.execute(select(Transaction).filter(Transaction.block_hash.contains([blockId]))) - - transactions = transactions.scalars().all() - - tx_outputs = await s.execute(select(TransactionOutput) - .where(TransactionOutput.transaction_id - .in_([tx.transaction_id for tx in transactions]))) - - tx_outputs = tx_outputs.scalars().all() - - tx_inputs = await s.execute(select(TransactionInput) - .where(TransactionInput.transaction_id - .in_([tx.transaction_id for tx in transactions]))) - - tx_inputs = tx_inputs.scalars().all() - - for tx in transactions: - tx_list.append({ - "inputs": [ - { - "previousOutpoint": { - "transactionId": tx_inp.previous_outpoint_hash, - "index": tx_inp.previous_outpoint_index - }, - "signatureScript": tx_inp.signature_script, - "sigOpCount": tx_inp.sig_op_count - } - for tx_inp in tx_inputs if tx_inp.transaction_id == tx.transaction_id], - "outputs": [ - { - "amount": tx_out.amount, - "scriptPublicKey": { - "scriptPublicKey": tx_out.script_public_key - }, - "verboseData": { - "scriptPublicKeyType": tx_out.script_public_key_type, - "scriptPublicKeyAddress": tx_out.script_public_key_address - } - } for tx_out in tx_outputs if tx_out.transaction_id == tx.transaction_id], - "subnetworkId": tx.subnetwork_id, - "verboseData": { - "transactionId": tx.transaction_id, - "hash": tx.hash, - "mass": tx.mass, - "blockHash": tx.block_hash, - "blockTime": tx.block_time - } - }) - - return tx_list \ No newline at end of file diff --git a/endpoints/get_circulating_supply.py b/endpoints/get_circulating_supply.py index eff9127..1297038 100644 --- a/endpoints/get_circulating_supply.py +++ b/endpoints/get_circulating_supply.py @@ -1,17 +1,8 @@ # encoding: utf-8 -from pydantic import BaseModel +from server import kaspad_client -from server import app, kaspad_client -from fastapi.responses import PlainTextResponse - -class CoinSupplyResponse(BaseModel): - circulatingSupply: str = "1000900697580640180" - maxSupply: str = "2900000000000000000" - - -@app.get("/info/coinsupply", response_model=CoinSupplyResponse, tags=["Kaspa network info"]) async def get_coinsupply(): """ Get $KAS coin supply information @@ -23,9 +14,8 @@ async def get_coinsupply(): "maxSupply": resp["getCoinSupplyResponse"]["maxSompi"] } -@app.get("/info/coinsupply/circulating", tags=["Kaspa network info"], - response_class=PlainTextResponse) -async def get_circulating_coins(in_billion : bool = False): + +async def get_circulating_coins(in_billion: bool = False): """ Get circulating amount of $KAS token as numerical value """ @@ -37,8 +27,6 @@ async def get_circulating_coins(in_billion : bool = False): return coins -@app.get("/info/coinsupply/total", tags=["Kaspa network info"], - response_class=PlainTextResponse) async def get_circulating_coins(): """ Get total amount of $KAS token as numerical value diff --git a/endpoints/get_halving.py b/endpoints/get_halving.py deleted file mode 100644 index 7cfe180..0000000 --- a/endpoints/get_halving.py +++ /dev/null @@ -1,54 +0,0 @@ -# encoding: utf-8 -import time -from datetime import datetime - -from pydantic import BaseModel -from starlette.responses import PlainTextResponse - -from helper.deflationary_table import DEFLATIONARY_TABLE -from server import app, kaspad_client - - -class HalvingResponse(BaseModel): - nextHalvingTimestamp: int = 1662837270000 - nextHalvingDate: str = '2022-09-10 19:38:52 UTC' - nextHalvingAmount: float = 155.123123 - - -@app.get("/info/halving", response_model=HalvingResponse | str, tags=["Kaspa network info"]) -async def get_halving(field: str | None = None): - """ - Returns information about chromatic halving - """ - resp = await kaspad_client.request("getBlockDagInfoRequest") - daa_score = int(resp["getBlockDagInfoResponse"]["virtualDaaScore"]) - - future_reward = 0 - daa_breakpoint = 0 - - daa_list = sorted(DEFLATIONARY_TABLE) - - for i, to_break_score in enumerate(daa_list): - if daa_score < to_break_score: - future_reward = DEFLATIONARY_TABLE[daa_list[i + 1]] - daa_breakpoint = to_break_score - break - - next_halving_timestamp = int(time.time() + (daa_breakpoint - daa_score)) - - if field == "nextHalvingTimestamp": - return PlainTextResponse(content=str(next_halving_timestamp)) - - elif field == "nextHalvingDate": - return PlainTextResponse(content=datetime.utcfromtimestamp(next_halving_timestamp) - .strftime('%Y-%m-%d %H:%M:%S UTC')) - - elif field == "nextHalvingAmount": - return PlainTextResponse(content=str(future_reward)) - - else: - return { - "nextHalvingTimestamp": next_halving_timestamp, - "nextHalvingDate": datetime.utcfromtimestamp(next_halving_timestamp).strftime('%Y-%m-%d %H:%M:%S UTC'), - "nextHalvingAmount": future_reward - } diff --git a/endpoints/get_hashrate.py b/endpoints/get_hashrate.py deleted file mode 100644 index 146d93a..0000000 --- a/endpoints/get_hashrate.py +++ /dev/null @@ -1,84 +0,0 @@ -# encoding: utf-8 -import json - -from pydantic import BaseModel -from sqlalchemy import select - -from dbsession import async_session -from helper import KeyValueStore -from models.Block import Block -from server import app, kaspad_client - -MAXHASH_CACHE = (0, 0) - - -class BlockHeader(BaseModel): - hash: str = "e6641454e16cff4f232b899564eeaa6e480b66069d87bee6a2b2476e63fcd887" - timestamp: str = "1656450648874" - difficulty: int = 1212312312 - daaScore: str = "19984482" - blueScore: str = "18483232" - - -class HashrateResponse(BaseModel): - hashrate: float = 12000132 - - -class MaxHashrateResponse(BaseModel): - hashrate: float = 12000132 - blockheader: BlockHeader - - -@app.get("/info/hashrate", response_model=HashrateResponse | str, tags=["Kaspa network info"]) -async def get_hashrate(stringOnly: bool = False): - """ - Returns the current hashrate for Kaspa network in TH/s. - """ - - resp = await kaspad_client.request("getBlockDagInfoRequest") - hashrate = resp["getBlockDagInfoResponse"]["difficulty"] * 2 - hashrate_in_th = hashrate / 1_000_000_000_000 - - if not stringOnly: - return { - "hashrate": hashrate_in_th - } - - else: - return f"{hashrate_in_th:.01f}" - - -@app.get("/info/hashrate/max", response_model=MaxHashrateResponse, tags=["Kaspa network info"]) -async def get_max_hashrate(): - """ - Returns the current hashrate for Kaspa network in TH/s. - """ - maxhash_last_value = json.loads((await KeyValueStore.get("maxhash_last_value")) or "{}") - maxhash_last_bluescore = int((await KeyValueStore.get("maxhash_last_bluescore")) or 0) - print(f"Start at {maxhash_last_bluescore}") - - async with async_session() as s: - block = (await s.execute(select(Block) - .filter(Block.blue_score > maxhash_last_bluescore) - .order_by(Block.difficulty.desc()).limit(1))).scalar() - - hashrate_new = block.difficulty * 2 - hashrate_old = maxhash_last_value.get("blockheader", {}).get("difficulty", 0) * 2 - - await KeyValueStore.set("maxhash_last_bluescore", str(block.blue_score)) - - if hashrate_new > hashrate_old: - response = {"hashrate": hashrate_new / 1_000_000_000_000, - "blockheader": - { - "hash": block.hash, - "timestamp": block.timestamp.isoformat(), - "difficulty": block.difficulty, - "daaScore": block.daa_score, - "blueScore": block.blue_score - } - } - await KeyValueStore.set("maxhash_last_value", json.dumps(response)) - return response - - return maxhash_last_value diff --git a/endpoints/get_health.py b/endpoints/get_health.py deleted file mode 100644 index 1105d2a..0000000 --- a/endpoints/get_health.py +++ /dev/null @@ -1,57 +0,0 @@ -# encoding: utf-8 -import hashlib -from datetime import datetime, timedelta -from typing import List - -from fastapi import HTTPException -from pydantic import BaseModel -from sqlalchemy import select - -from dbsession import async_session -from models.Transaction import Transaction -from server import app, kaspad_client - - -class KaspadResponse(BaseModel): - kaspadHost: str = "" - serverVersion: str = "0.12.6" - isUtxoIndexed: bool = True - isSynced: bool = True - p2pId: str = "1231312" - - -class HealthResponse(BaseModel): - kaspadServers: List[KaspadResponse] - - -@app.get("/info/health", response_model=HealthResponse, tags=["Kaspa network info"]) -async def health_state(): - """ - Returns the current hashrate for Kaspa network in TH/s. - """ - await kaspad_client.initialize_all() - - kaspads = [] - - async with async_session() as s: - last_block_time = (await s.execute(select(Transaction.block_time) - .limit(1) - .order_by(Transaction.block_time.desc()))).scalar() - - time_diff = datetime.now() - datetime.fromtimestamp(last_block_time / 1000) - - if time_diff > timedelta(minutes=10): - raise HTTPException(status_code=500, detail="Transactions not up to date") - - for i, kaspad_info in enumerate(kaspad_client.kaspads): - kaspads.append({ - "isSynced": kaspad_info.is_synced, - "isUtxoIndexed": kaspad_info.is_utxo_indexed, - "p2pId": hashlib.sha256(kaspad_info.p2p_id.encode()).hexdigest(), - "kaspadHost": f"KASPAD_HOST_{i + 1}", - "serverVersion": kaspad_info.server_version - }) - - return { - "kaspadServers": kaspads - } diff --git a/endpoints/get_kaspad_info.py b/endpoints/get_kaspad_info.py deleted file mode 100644 index b450a87..0000000 --- a/endpoints/get_kaspad_info.py +++ /dev/null @@ -1,25 +0,0 @@ -# encoding: utf-8 -import hashlib - -from pydantic import BaseModel - -from server import app, kaspad_client - - -class KaspadInfoResponse(BaseModel): - mempoolSize: str = "1" - serverVersion: str = "0.12.2" - isUtxoIndexed: bool = True - isSynced: bool = True - p2pIdHashed : str = "36a17cd8644eef34fc7fe4719655e06dbdf117008900c46975e66c35acd09b01" - - -@app.get("/info/kaspad", response_model=KaspadInfoResponse, tags=["Kaspa network info"]) -async def get_kaspad_info(): - """ - Get some information for kaspad instance, which is currently connected. - """ - resp = await kaspad_client.request("getInfoRequest") - p2p_id = resp["getInfoResponse"].pop("p2pId") - resp["getInfoResponse"]["p2pIdHashed"] = hashlib.sha256(p2p_id.encode()).hexdigest() - return resp["getInfoResponse"] diff --git a/endpoints/get_marketcap.py b/endpoints/get_marketcap.py deleted file mode 100644 index 8979a42..0000000 --- a/endpoints/get_marketcap.py +++ /dev/null @@ -1,32 +0,0 @@ -# encoding: utf-8 - -import requests -from pydantic import BaseModel - -from helper import get_kas_price -from server import app, kaspad_client - - -class MarketCapResponse(BaseModel): - marketcap: int = 12000132 - - -@app.get("/info/marketcap", response_model=MarketCapResponse | str, tags=["Kaspa network info"]) -async def get_marketcap(stringOnly: bool = False): - """ - Get $KAS price and market cap. Price info is from coingecko.com - """ - kas_price = get_kas_price() - resp = await kaspad_client.request("getCoinSupplyRequest") - mcap = round(float(resp["getCoinSupplyResponse"]["circulatingSompi"]) / 100000000 * kas_price) - - if not stringOnly: - return { - "marketcap": mcap - } - else: - if mcap < 1000000000: - return f"{round(mcap / 1000000,1)}M" - else: - return f"{round(mcap / 1000000000,1)}B" - diff --git a/endpoints/get_network.py b/endpoints/get_network.py index 2616279..0632d5b 100644 --- a/endpoints/get_network.py +++ b/endpoints/get_network.py @@ -1,30 +1,8 @@ # encoding: utf-8 -from typing import List -from pydantic import BaseModel +from server import kaspad_client -from server import app, kaspad_client - -class NetworkResponse(BaseModel): - networkName: str = "kaspa-mainnet" - blockCount: str = "261357" - headerCount: str = "23138783" - tipHashes: List[str] = [ - "efdbe104c6275cf881583fba77834c8528fd1ab059f6b4737c42564d0d9fedbc", - "6affbe62baef0f1a562f166b9857844b03b51a8ec9b8417ceb308d53fdc239a2" - ] - difficulty: float = 3887079905014.09 - pastMedianTime: str = "1656456088196" - virtualParentHashes: List[str] = [ - "6affbe62baef0f1a562f166b9857844b03b51a8ec9b8417ceb308d53fdc239a2", - "efdbe104c6275cf881583fba77834c8528fd1ab059f6b4737c42564d0d9fedbc" - ] - pruningPointHash: str = "5d32a9403273a34b6551b84340a1459ddde2ae6ba59a47987a6374340ba41d5d" - virtualDaaScore: str = "19989984" - - -@app.get("/info/network", response_model=NetworkResponse, tags=["Kaspa network info"]) async def get_network(): """ Get some global kaspa network information diff --git a/endpoints/get_price.py b/endpoints/get_price.py deleted file mode 100644 index 1424666..0000000 --- a/endpoints/get_price.py +++ /dev/null @@ -1,31 +0,0 @@ -# encoding: utf-8 - -from pydantic import BaseModel -from starlette.responses import PlainTextResponse - -from helper import get_kas_price, get_kas_market_data -from server import app - - -class PriceResponse(BaseModel): - price: float = 0.025235 - - -@app.get("/info/price", response_model=PriceResponse | str, tags=["Kaspa network info"]) -async def get_price(stringOnly: bool = False): - """ - Returns the current price for Kaspa in USD. - """ - if stringOnly: - return PlainTextResponse(content=str(get_kas_price())) - - return {"price": get_kas_price()} - -@app.get("/info/market-data", - tags=["Kaspa network info"], - include_in_schema=False) -async def get_market_data(): - """ - Returns market data for kaspa. - """ - return get_kas_market_data() diff --git a/endpoints/get_transactions.py b/endpoints/get_transactions.py deleted file mode 100644 index 605f43a..0000000 --- a/endpoints/get_transactions.py +++ /dev/null @@ -1,241 +0,0 @@ -# encoding: utf-8 - -from enum import Enum -from typing import List - -from fastapi import Path, HTTPException, Query -from pydantic import BaseModel, parse_obj_as -from sqlalchemy import Integer, cast -from sqlalchemy.future import select - -from dbsession import async_session -from endpoints import filter_fields -from models.Block import Block -from models.Transaction import Transaction, TransactionOutput, TransactionInput -from server import app - -DESC_RESOLVE_PARAM = "Use this parameter if you want to fetch the TransactionInput previous outpoint details." \ - " Light fetches only the address and amount. Full fetches the whole TransactionOutput and " \ - "adds it into each TxInput." - - -class TxOutput(BaseModel): - id: int - transaction_id: str - index: int - amount: int - script_public_key: str - script_public_key_address: str - script_public_key_type: str - accepting_block_hash: str | None - - class Config: - orm_mode = True - - -class TxInput(BaseModel): - id: int - transaction_id: str - index: int - previous_outpoint_hash: str - previous_outpoint_index: str - previous_outpoint_resolved: TxOutput | None - previous_outpoint_address: str | None - previous_outpoint_amount: int | None - signature_script: str - sig_op_count: str - - class Config: - orm_mode = True - - -class TxModel(BaseModel): - subnetwork_id: str | None - transaction_id: str | None - hash: str | None - mass: str | None - block_hash: List[str] | None - block_time: int | None - is_accepted: bool | None - accepting_block_hash: str | None - accepting_block_blue_score: int | None - inputs: List[TxInput] | None - outputs: List[TxOutput] | None - - class Config: - orm_mode = True - - -class TxSearch(BaseModel): - transactionIds: List[str] - - -class PreviousOutpointLookupMode(str, Enum): - no = "no" - light = "light" - full = "full" - - -@app.get("/transactions/{transactionId}", - response_model=TxModel, - tags=["Kaspa transactions"], - response_model_exclude_unset=True) -async def get_transaction(transactionId: str = Path(regex="[a-f0-9]{64}"), - inputs: bool = True, - outputs: bool = True, - resolve_previous_outpoints: PreviousOutpointLookupMode = - Query(default=PreviousOutpointLookupMode.no, - description=DESC_RESOLVE_PARAM)): - """ - Get block information for a given block id - """ - async with async_session() as s: - tx = await s.execute(select(Transaction, Block.blue_score) \ - .join(Block, Transaction.accepting_block_hash == Block.hash, isouter=True) - .filter(Transaction.transaction_id == transactionId)) - - tx = tx.first() - - tx_outputs = None - tx_inputs = None - - if outputs: - tx_outputs = await s.execute(select(TransactionOutput) \ - .filter(TransactionOutput.transaction_id == transactionId)) - - tx_outputs = tx_outputs.scalars().all() - - if inputs: - if resolve_previous_outpoints in ["light", "full"]: - tx_inputs = await s.execute(select(TransactionInput, TransactionOutput) - .outerjoin(TransactionOutput, - (TransactionOutput.transaction_id == TransactionInput.previous_outpoint_hash) & - (TransactionOutput.index == cast(TransactionInput.previous_outpoint_index, Integer))) - .filter(TransactionInput.transaction_id == transactionId)) - - tx_inputs = tx_inputs.all() - - if resolve_previous_outpoints in ["light", "full"]: - for tx_in, tx_prev_outputs in tx_inputs: - # it is possible, that the old tx is not in database. Leave fields empty - if not tx_prev_outputs: - tx_in.previous_outpoint_amount = None - tx_in.previous_outpoint_address = None - if resolve_previous_outpoints == "full": - tx_in.previous_outpoint_resolved = None - continue - - tx_in.previous_outpoint_amount = tx_prev_outputs.amount - tx_in.previous_outpoint_address = tx_prev_outputs.script_public_key_address - if resolve_previous_outpoints == "full": - tx_in.previous_outpoint_resolved = tx_prev_outputs - - # remove unneeded list - tx_inputs = [x[0] for x in tx_inputs] - - else: - tx_inputs = await s.execute(select(TransactionInput) \ - .filter(TransactionInput.transaction_id == transactionId)) - tx_inputs = tx_inputs.scalars().all() - - if tx: - return { - "subnetwork_id": tx.Transaction.subnetwork_id, - "transaction_id": tx.Transaction.transaction_id, - "hash": tx.Transaction.hash, - "mass": tx.Transaction.mass, - "block_hash": tx.Transaction.block_hash, - "block_time": tx.Transaction.block_time, - "is_accepted": tx.Transaction.is_accepted, - "accepting_block_hash": tx.Transaction.accepting_block_hash, - "accepting_block_blue_score": tx.blue_score, - "outputs": parse_obj_as(List[TxOutput], tx_outputs) if tx_outputs else None, - "inputs": parse_obj_as(List[TxInput], tx_inputs) if tx_inputs else None - } - else: - raise HTTPException(status_code=404, detail="Transaction not found") - - -@app.post("/transactions/search", - response_model=List[TxModel], - tags=["Kaspa transactions"], - response_model_exclude_unset=True) -async def search_for_transactions(txSearch: TxSearch, - fields: str = "", - resolve_previous_outpoints: PreviousOutpointLookupMode = - Query(default=PreviousOutpointLookupMode.no, - description=DESC_RESOLVE_PARAM)): - """ - Get block information for a given block id - """ - fields = fields.split(",") if fields else [] - - async with async_session() as s: - tx_list = await s.execute(select(Transaction, Block.blue_score) - .join(Block, Transaction.accepting_block_hash == Block.hash, isouter=True) - .filter(Transaction.transaction_id.in_(txSearch.transactionIds)) - .order_by(Transaction.block_time.desc())) - - tx_list = tx_list.all() - - if not fields or "inputs" in fields: - # join TxOutputs if needed - if resolve_previous_outpoints in ["light", "full"]: - tx_inputs = await s.execute(select(TransactionInput, TransactionOutput) - .outerjoin(TransactionOutput, - (TransactionOutput.transaction_id == TransactionInput.previous_outpoint_hash) & - (TransactionOutput.index == cast(TransactionInput.previous_outpoint_index, Integer))) - .filter(TransactionInput.transaction_id.in_(txSearch.transactionIds))) - - # without joining previous_tx_outputs - else: - tx_inputs = await s.execute(select(TransactionInput) - .filter(TransactionInput.transaction_id.in_(txSearch.transactionIds))) - tx_inputs = tx_inputs.all() - - if resolve_previous_outpoints in ["light", "full"]: - for tx_in, tx_prev_outputs in tx_inputs: - - # it is possible, that the old tx is not in database. Leave fields empty - if not tx_prev_outputs: - tx_in.previous_outpoint_amount = None - tx_in.previous_outpoint_address = None - if resolve_previous_outpoints == "full": - tx_in.previous_outpoint_resolved = None - continue - - tx_in.previous_outpoint_amount = tx_prev_outputs.amount - tx_in.previous_outpoint_address = tx_prev_outputs.script_public_key_address - if resolve_previous_outpoints == "full": - tx_in.previous_outpoint_resolved = tx_prev_outputs - - # remove unneeded list - tx_inputs = [x[0] for x in tx_inputs] - - else: - tx_inputs = None - - if not fields or "outputs" in fields: - tx_outputs = await s.execute(select(TransactionOutput) \ - .filter(TransactionOutput.transaction_id.in_(txSearch.transactionIds))) - tx_outputs = tx_outputs.scalars().all() - else: - tx_outputs = None - - return (filter_fields({ - "subnetwork_id": tx.Transaction.subnetwork_id, - "transaction_id": tx.Transaction.transaction_id, - "hash": tx.Transaction.hash, - "mass": tx.Transaction.mass, - "block_hash": tx.Transaction.block_hash, - "block_time": tx.Transaction.block_time, - "is_accepted": tx.Transaction.is_accepted, - "accepting_block_hash": tx.Transaction.accepting_block_hash, - "accepting_block_blue_score": tx.blue_score, - "outputs": parse_obj_as(List[TxOutput], - [x for x in tx_outputs if x.transaction_id == tx.Transaction.transaction_id]) - if tx_outputs else None, # parse only if needed - "inputs": parse_obj_as(List[TxInput], - [x for x in tx_inputs if x.transaction_id == tx.Transaction.transaction_id]) - if tx_inputs else None # parse only if needed - }, fields) for tx in tx_list) diff --git a/endpoints/get_utxos.py b/endpoints/get_utxos.py deleted file mode 100644 index 1f9ce9e..0000000 --- a/endpoints/get_utxos.py +++ /dev/null @@ -1,49 +0,0 @@ -# encoding: utf-8 - -from typing import List - -from fastapi import Path, HTTPException -from pydantic import BaseModel - -from server import app, kaspad_client - - -class OutpointModel(BaseModel): - transactionId: str = "ef62efbc2825d3ef9ec1cf9b80506876ac077b64b11a39c8ef5e028415444dc9" - index: int = 0 - - -class ScriptPublicKeyModel(BaseModel): - scriptPublicKey: str = "20c5629ce85f6618cd3ed1ac1c99dc6d3064ed244013555c51385d9efab0d0072fac" - - -class UtxoModel(BaseModel): - amount: str = "11501593788", - scriptPublicKey: ScriptPublicKeyModel - blockDaaScore: str = "18867232" - - -class UtxoResponse(BaseModel): - address: str = "kaspa:qrzk988gtanp3nf76xkpexwud5cxfmfygqf42hz38pwea74s6qrj75jee85nj" - outpoint: OutpointModel - utxoEntry: UtxoModel - - -@app.get("/addresses/{kaspaAddress}/utxos", response_model=List[UtxoResponse], tags=["Kaspa addresses"]) -async def get_utxos_for_address(kaspaAddress: str = Path( - description="Kaspa address as string e.g. kaspa:qqkqkzjvr7zwxxmjxjkmxxdwju9kjs6e9u82uh59z07vgaks6gg62v8707g73", - regex="^kaspa\:[a-z0-9]{61,63}$")): - """ - Lists all open utxo for a given kaspa address - """ - resp = await kaspad_client.request("getUtxosByAddressesRequest", - params={ - "addresses": [kaspaAddress] - }, timeout=120) - try: - return (utxo for utxo in resp["getUtxosByAddressesResponse"]["entries"] if utxo["address"] == kaspaAddress) - except KeyError: - if "getUtxosByAddressesResponse" in resp and "error" in resp["getUtxosByAddressesResponse"]: - raise HTTPException(status_code=400, detail=resp["getUtxosByAddressesResponse"]["error"]) - else: - return [] diff --git a/endpoints/get_virtual_chain_blue_score.py b/endpoints/get_virtual_chain_blue_score.py index 8e6a241..fb8c80a 100644 --- a/endpoints/get_virtual_chain_blue_score.py +++ b/endpoints/get_virtual_chain_blue_score.py @@ -1,16 +1,8 @@ # encoding: utf-8 -from typing import List -from pydantic import BaseModel +from server import kaspad_client -from server import app, kaspad_client - -class BlockdagResponse(BaseModel): - blueScore: int = 260890 - - -@app.get("/info/virtual-chain-blue-score", response_model=BlockdagResponse, tags=["Kaspa network info"]) async def get_virtual_selected_parent_blue_score(): """ Returns the blue score of virtual selected parent diff --git a/endpoints/get_vspc.py b/endpoints/get_vspc.py deleted file mode 100644 index b8d68f8..0000000 --- a/endpoints/get_vspc.py +++ /dev/null @@ -1,40 +0,0 @@ -# encoding: utf-8 -from typing import List - -from fastapi import HTTPException -from pydantic import BaseModel - -from server import app, kaspad_client - - -class AcceptedTransactionIdsModel(BaseModel): - acceptingBlockHash: str = "78c1492fa4c88f3ef1c3b14d3bc228a09fdd49c9b224571924b8e256806a495b" - acceptedTransactionIds: List[str] = ["eb5b16f01d209e036c5b7e2674fb9fd63c4c5b399b1b10d8daef2369c07e676c", - "2f37c0fb935cfcee07cfe2494453a4899f2415fad77dd2cfc058d9109de52e71"] - - -class VscpResponse(BaseModel): - removedChainBlockHashes: List[str] = [] - addedChainBlockHashes: List[str] = [] - acceptedTransactionIds: List[AcceptedTransactionIdsModel] - - -@app.get("/info/get-vscp-from-block", response_model=VscpResponse, tags=["Kaspa network info"]) -async def get_virtual_selected_parent_chain_from_block( - startHash: str, - includeAcceptedTransactionIds: bool = True): - """ - GetVirtualSelectedParentChainFromBlockRequestMessage requests the virtual selected parent chain from - some startHash to this kaspad's current virtual. - """ - resp = await kaspad_client.request("getVirtualSelectedParentChainFromBlockRequest", - params={ - "startHash": startHash, - "includeAcceptedTransactionIds": includeAcceptedTransactionIds - }) - resp = resp["getVirtualSelectedParentChainFromBlockResponse"] - - if resp.get('error'): - raise HTTPException(400, detail=resp.get('error').get('message')) - - return resp diff --git a/endpoints/kaspad_requests/__init__.py b/endpoints/kaspad_requests/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/endpoints/kaspad_requests/submit_transaction_request.py b/endpoints/kaspad_requests/submit_transaction_request.py deleted file mode 100644 index 1df4c58..0000000 --- a/endpoints/kaspad_requests/submit_transaction_request.py +++ /dev/null @@ -1,118 +0,0 @@ -# encoding: utf-8 - -from typing import List - -from pydantic import BaseModel -from starlette.responses import JSONResponse - -from server import app, kaspad_client - - -class SubmitTxOutpoint(BaseModel): - transactionId: str - index: int - - -class SubmitTxInput(BaseModel): - previousOutpoint: SubmitTxOutpoint - signatureScript: str - sequence: int - sigOpCount: int - - -class SubmitTxScriptPublicKey(BaseModel): - version: int - scriptPublicKey: str - - -class SubmitTxOutput(BaseModel): - amount: int - scriptPublicKey: SubmitTxScriptPublicKey - # verboseData: TxOutputVerboseData | None - - -class SubmitTxModel(BaseModel): - version: int - inputs: List[SubmitTxInput] - outputs: List[SubmitTxOutput] - lockTime: int | None = 0 - subnetworkId: str | None - - -class SubmitTransactionRequest(BaseModel): - transaction: SubmitTxModel - allowOrphan: bool = True - - -class SubmitTransactionResponse(BaseModel): - transactionId: str | None - error: str | None - - -@app.post("/transactions", - tags=["Kaspa transactions"], - response_model_exclude_unset=True, - responses={200: {"model": SubmitTransactionResponse}, - 400: {"model": SubmitTransactionResponse}}) -async def submit_a_new_transaction(body: SubmitTransactionRequest): - """ - Forwards the body directly to kaspad with the command submitTransactionRequest - """ - tx_resp = await kaspad_client.request("submitTransactionRequest", - params=body.dict()) - - tx_resp = tx_resp["submitTransactionResponse"] - - # if error in response - if "error" in tx_resp: - return JSONResponse(status_code=400, - content={"error": tx_resp["error"].get("message", "")}) - - # if transactionId is in response - elif "transactionId" in tx_resp: - return { - "transactionId": tx_resp["transactionId"] - } - - # something else went wrong - else: - return JSONResponse(status_code=400, - content={"error": str(tx_resp)}) - - -""" -{ - "transaction": { - "version": 0, - "inputs": [ - { - "previousOutpoint": { - "transactionId": "fa99f98b8e9b0758100d181eccb35a4c053b8265eccb5a89aadd794e087d9820", - "index": 1 - }, - "signatureScript": "4187173244180496d67a94dc78f3d3651bc645139b636a9c79a4f1d36fdcc718e88e9880eeb0eb208d0c110f31a306556457bc37e1044aeb3fdd303bd1a8c1b84601", - "sequence": 0, - "sigOpCount": 1 - } - ], - "outputs": [ - { - "amount": 100000, - "scriptPublicKey": { - "scriptPublicKey": "20167f5647a0e88ed3ac7834b5de4a5f0e56a438bcb6c97186a2c935303290ef6fac", - "version": 0 - } - }, - { - "amount": 183448, - "scriptPublicKey": { - "scriptPublicKey": "2010352c822bf3c67637c84ea09ff90edc11fa509475ae1884cf5b971e53afd472ac", - "version": 0 - } - } - ], - "lockTime": 0, - "subnetworkId": "0000000000000000000000000000000000000000" - } -} -""" diff --git a/main.py b/main.py index 65973e9..9fb7ef5 100644 --- a/main.py +++ b/main.py @@ -7,17 +7,6 @@ from starlette.responses import RedirectResponse import sockets -from endpoints import get_balance, get_utxos, get_blocks, get_blockdag, get_circulating_supply, get_kaspad_info, \ - get_network, get_price -from endpoints.get_address_transactions import get_transactions_for_address -from endpoints.get_blockreward import get_blockreward -from endpoints.get_halving import get_halving -from endpoints.get_hashrate import get_hashrate -from endpoints.get_health import health_state -from endpoints.get_marketcap import get_marketcap -from endpoints.get_transactions import get_transaction -from endpoints.get_virtual_chain_blue_score import get_virtual_selected_parent_blue_score -from endpoints.kaspad_requests.submit_transaction_request import submit_a_new_transaction from server import app, kaspad_client from sockets import blocks from sockets.blockdag import periodical_blockdag @@ -25,15 +14,8 @@ from sockets.coinsupply import periodic_coin_supply print( - f"Loaded: {get_balance}, {get_utxos}, {get_blocks}, {get_blockdag}, {get_circulating_supply}, " - f"{get_kaspad_info}, {get_network}, {get_marketcap}, {get_hashrate}, {get_blockreward}, {sockets.join_room}" - f"{periodic_coin_supply} {periodical_blockdag} {get_halving} {health_state} {get_transaction}" - f"{get_virtual_selected_parent_blue_score} {periodical_blue_score} {get_transactions_for_address}" - f"{submit_a_new_transaction} {get_price}") - -if os.getenv('VSPC_REQUEST') == 'true': - from endpoints.get_vspc import get_virtual_selected_parent_chain_from_block - print(get_virtual_selected_parent_chain_from_block) + f"Loaded: {sockets.join_room}" + f"{periodic_coin_supply} {periodical_blockdag} {periodical_blue_score}") BLOCKS_TASK = None # type: Task diff --git a/models/Block.py b/models/Block.py deleted file mode 100644 index 5952c38..0000000 --- a/models/Block.py +++ /dev/null @@ -1,29 +0,0 @@ -from sqlalchemy import Column, String, Float, Boolean, Integer, BigInteger, TIMESTAMP -from sqlalchemy.dialects.postgresql import ARRAY - -from dbsession import Base - - -class Block(Base): - __tablename__ = 'blocks' - - hash = Column(String, primary_key=True) - accepted_id_merkle_root = Column(String) - difficulty = Column(Float) - # childrenHashes = Column(JSONB) - is_chain_block = Column(Boolean) - merge_set_blues_hashes = Column(ARRAY(String)) - merge_set_reds_hashes = Column(ARRAY(String)) - selected_parent_hash = Column(String) - bits = Column(Integer) - blue_score = Column(BigInteger) - blue_work = Column(String) - daa_score = Column(BigInteger) - hash_merkle_root = Column(String) - nonce = Column(String) - parents = Column(ARRAY(String)) - pruning_point = Column(String) - timestamp = Column(TIMESTAMP(timezone=False)) - utxo_commitment = Column(String) - version = Column(Integer) - diff --git a/models/Transaction.py b/models/Transaction.py deleted file mode 100644 index 963be1d..0000000 --- a/models/Transaction.py +++ /dev/null @@ -1,42 +0,0 @@ -from sqlalchemy import Column, String, Integer, BigInteger, Boolean, ForeignKey -from sqlalchemy.dialects.postgresql import ARRAY - -from dbsession import Base - - -class Transaction(Base): - __tablename__ = 'transactions' - subnetwork_id = Column(String) # "0000000000000000000000000000000000000000", - transaction_id = Column(String, - primary_key=True) # "bedea078f74f241e7d755a98c9e39fda1dc56491dc7718485a8f221f73f03061", - hash = Column(String) # "a5f99f4dc55693124e7c6b75dc3e56b60db381a74716046dbdcae9210ce1052f", - mass = Column(String) # "2036", - block_hash = Column(ARRAY(String)) # "1b41af8cfe1851243bedf596b7299c039b86b2fef8eb4204b04f954da5d2ab0f", - block_time = Column(BigInteger) # "1663286480803" - is_accepted = Column(Boolean, default=False) - accepting_block_hash = Column(String, nullable=True) - - -class TransactionOutput(Base): - __tablename__ = 'transactions_outputs' - id = Column(Integer, primary_key=True) - transaction_id = Column(String, ForeignKey('transactions.transaction_id')) - index = Column(Integer) - amount = Column(BigInteger) - script_public_key = Column(String) - script_public_key_address = Column(String) - script_public_key_type = Column(String) - accepting_block_hash = Column(String) - - -class TransactionInput(Base): - __tablename__ = 'transactions_inputs' - id = Column(Integer, primary_key=True) - transaction_id = Column(String) - index = Column(Integer) - - previous_outpoint_hash = Column(String) # "ebf6da83db96d312a107a2ced19a01823894c9d7072ed0d696a9a152fd81485e" - previous_outpoint_index = Column(String) # "ebf6da83db96d312a107a2ced19a01823894c9d7072ed0d696a9a152fd81485e" - - signature_script = Column(String) # "41c903159094....281a1d26f70b0037d600554e01", - sig_op_count = Column(Integer) diff --git a/models/TxAddrMapping.py b/models/TxAddrMapping.py deleted file mode 100644 index 22f1732..0000000 --- a/models/TxAddrMapping.py +++ /dev/null @@ -1,12 +0,0 @@ -from sqlalchemy import Column, String, BigInteger, Boolean - -from dbsession import Base - - -class TxAddrMapping(Base): - __tablename__ = 'tx_id_address_mapping' - transaction_id = Column(String) - address = Column(String) - block_time = Column(BigInteger) - is_accepted = Column(Boolean, default=False) - id = Column(BigInteger, primary_key=True) diff --git a/models/Variable.py b/models/Variable.py deleted file mode 100644 index f7ae535..0000000 --- a/models/Variable.py +++ /dev/null @@ -1,9 +0,0 @@ -from sqlalchemy import Column, String, Text - -from dbsession import Base - - -class KeyValueModel(Base): - __tablename__ = 'vars' - key = Column(String, primary_key=True) - value = Column(Text) diff --git a/models/__init__.py b/models/__init__.py deleted file mode 100644 index e69de29..0000000