Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TESTNET=true environment variable for testnet #37

Merged
merged 33 commits into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 36 additions & 21 deletions .github/workflows/docker-testimage.yml
Original file line number Diff line number Diff line change
@@ -1,25 +1,40 @@
name: Docker Image TESTBUILD

on:
workflow_dispatch
name: Docker Image
on: push

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
os: [ubuntu-latest]
arch: [amd64, arm64]

runs-on: ${{ matrix.os }}

steps:
- name: Checkout
uses: actions/checkout@v3
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: lamer1
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: supertypo/kaspa-rest-server:test
file: ./docker/Dockerfile
build-args: |
version=${{github.ref_name}}
- name: Add SHORT_SHA env property with commit short sha
run: echo "SHORT_SHA=`echo ${GITHUB_SHA} | cut -c1-8`" >> $GITHUB_ENV
- name: Checkout code
uses: actions/checkout@v2

- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: lamer1
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}

- name: Set up QEMU (for ARM64 emulation)
if: matrix.arch == 'arm64'
run: |
sudo apt-get install -y qemu-user-static

- name: Set up Docker Buildx (for multi-platform builds)
uses: docker/setup-buildx-action@v1

- name: Build and push Docker image
run: |
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t supertypo/kaspa-rest-server:${SHORT_SHA} \
--push .

docker buildx imagetools inspect supertypo/kaspa-rest-server:${SHORT_SHA}
24 changes: 24 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
FROM python:3.12-slim

ARG REPO_DIR

EXPOSE 8000

ENV KASPAD_HOST_1=n.seeder1.kaspad.net:16110
ARG version
ENV VERSION=$version

RUN apt update
RUN apt install uvicorn gunicorn -y

WORKDIR /app
COPY . .

RUN python -m pip install --upgrade pip
RUN pip install poetry
RUN poetry install --no-root --no-interaction

# make pipenv commands still running
RUN ln /usr/local/bin/poetry /usr/local/bin/pipenv

CMD poetry run gunicorn -b 0.0.0.0:8000 -w 4 -k uvicorn.workers.UvicornWorker main:app --timeout 120
1,021 changes: 0 additions & 1,021 deletions Pipfile.lock

This file was deleted.

9 changes: 9 additions & 0 deletions constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import os

IS_TESTNET = os.getenv('TESTNET', 'false').lower() == 'true'
REGEX_KASPA_ADDRESS = "^kaspa:[a-z0-9]{61,63}$" if not IS_TESTNET else "^kaspatest:[a-z0-9]{61,63}$"

# address constants
ADDRESS_PREFIX = "kaspatest" if IS_TESTNET else "kaspa"
ADDRESS_EXAMPLE = "kaspatest:qpqz2vxj23kvh0m73ta2jjn2u4cv4tlufqns2eap8mxyyt0rvrxy6ejkful67" if IS_TESTNET \
else "kaspa:qqkqkzjvr7zwxxmjxjkmxxdwju9kjs6e9u82uh59z07vgaks6gg62v8707g73"
35 changes: 0 additions & 35 deletions docker/Dockerfile

This file was deleted.

15 changes: 14 additions & 1 deletion endpoints/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# encoding: utf-8
import os
from fastapi import HTTPException
from functools import wraps

from fastapi import HTTPException
from constants import IS_TESTNET


def filter_fields(response_dict, fields):
Expand All @@ -23,3 +24,15 @@ async def wrapper(*args, **kwargs):
return await func(*args, **kwargs)

return wrapper


def mainnet_only(func):
@wraps(func)
async def wrapper(*args, **kwargs):
if IS_TESTNET:
raise HTTPException(status_code=503, detail="Endpoint not available. "
"This endpoint is only available in mainnet.")
return await func(*args, **kwargs)

return wrapper

18 changes: 9 additions & 9 deletions endpoints/get_address_transactions.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# encoding: utf-8
import os
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 typing import List

from constants import ADDRESS_EXAMPLE, REGEX_KASPA_ADDRESS
from dbsession import async_session
from endpoints import sql_db_only
from endpoints.get_transactions import search_for_transactions, TxSearch, TxModel
Expand Down Expand Up @@ -46,9 +47,8 @@ class PreviousOutpointLookupMode(str, Enum):
@sql_db_only
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}$")):
description=f"Kaspa address as string e.g. {ADDRESS_EXAMPLE}",
regex=REGEX_KASPA_ADDRESS)):
"""
Get all transactions for a given address from database
"""
Expand Down Expand Up @@ -92,8 +92,8 @@ async def get_transactions_for_address(
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}$"),
f"{ADDRESS_EXAMPLE}",
regex=REGEX_KASPA_ADDRESS),
limit: int = Query(
description="The number of records to get",
ge=1,
Expand Down Expand Up @@ -136,8 +136,8 @@ async def get_full_transactions_for_address(
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}$")
f"{ADDRESS_EXAMPLE}",
regex=REGEX_KASPA_ADDRESS)
):
"""
Count the number of transactions associated with this address
Expand Down
9 changes: 5 additions & 4 deletions endpoints/get_balance.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
# encoding: utf-8

import os
from fastapi import Path, HTTPException
from pydantic import BaseModel

from constants import ADDRESS_EXAMPLE, REGEX_KASPA_ADDRESS, IS_TESTNET
from server import app, kaspad_client


class BalanceResponse(BaseModel):
address: str = "kaspa:pzhh76qc82wzduvsrd9xh4zde9qhp0xc8rl7qu2mvl2e42uvdqt75zrcgpm00"
address: str = ADDRESS_EXAMPLE
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}$")):
description=f"Kaspa address as string e.g. {ADDRESS_EXAMPLE}",
regex=REGEX_KASPA_ADDRESS)):
"""
Get balance for a given kaspa address
"""
Expand Down
3 changes: 3 additions & 0 deletions endpoints/get_price.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from pydantic import BaseModel
from starlette.responses import PlainTextResponse

from endpoints import mainnet_only
from helper import get_kas_price, get_kas_market_data
from server import app

Expand All @@ -12,6 +13,7 @@ class PriceResponse(BaseModel):


@app.get("/info/price", response_model=PriceResponse | str, tags=["Kaspa network info"])
@mainnet_only
async def get_price(stringOnly: bool = False):
"""
Returns the current price for Kaspa in USD.
Expand All @@ -25,6 +27,7 @@ async def get_price(stringOnly: bool = False):
@app.get("/info/market-data",
tags=["Kaspa network info"],
include_in_schema=False)
@mainnet_only
async def get_market_data():
"""
Returns market data for kaspa.
Expand Down
12 changes: 6 additions & 6 deletions endpoints/get_utxos.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# encoding: utf-8

from typing import List

import os
from fastapi import Path, HTTPException
from pydantic import BaseModel
from typing import List

from constants import REGEX_KASPA_ADDRESS, ADDRESS_EXAMPLE
from server import app, kaspad_client


Expand All @@ -24,15 +24,15 @@ class UtxoModel(BaseModel):


class UtxoResponse(BaseModel):
address: str = "kaspa:qrzk988gtanp3nf76xkpexwud5cxfmfygqf42hz38pwea74s6qrj75jee85nj"
address: str = ADDRESS_EXAMPLE
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}$")):
description=f"Kaspa address as string e.g. {ADDRESS_EXAMPLE}",
regex=REGEX_KASPA_ADDRESS)):
"""
Lists all open utxo for a given kaspa address
"""
Expand Down
Loading
Loading