Skip to content

Commit

Permalink
Merge branch 'feature/11-validation' into feature/15-pytest
Browse files Browse the repository at this point in the history
  • Loading branch information
y-chan committed Nov 13, 2020
2 parents 01f2237 + eff7c5b commit ebd0825
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 15 deletions.
13 changes: 11 additions & 2 deletions asns/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ class TokenAndTxItem(TokenItem):
rawTransaction: str


class TokenAndTxAndContractItem(TokenAndTxItem):
contract: str


class RegisterSwapItem(TokenItem):
wantCurrency: str
wantAmount: int
Expand All @@ -91,7 +95,7 @@ class RegisterSwapItem(TokenItem):
receiveAddress: str


class InitiateSwapItem(TokenAndTxItem):
class InitiateSwapItem(TokenAndTxAndContractItem):
selectedSwap: str
receiveAddress: str

Expand All @@ -103,6 +107,7 @@ class RedeemSwapItem(TokenAndTxItem):
@api.exception_handler(StarletteHTTPException)
async def http_exception_handler(_: Request, exc: StarletteHTTPException):
return JSONResponse(
status_code=exc.status_code,
content=jsonable_encoder({"status": ResponseStatus.FAILED, "error": str(exc.detail)})
)

Expand Down Expand Up @@ -273,13 +278,15 @@ async def initiate_swap(item: InitiateSwapItem, commons: DBCommons = Depends(db_
)

if result is None:
contract = item.contract
initiate_raw_tx = item.rawTransaction
receive_address = item.receiveAddress

raw_token = b58.a2b_base58(token)
hashed_token = sha256d(raw_token)

selected_swap_data.swap_status = SwapStatus.INITIATED
selected_swap_data.i_contract = contract
selected_swap_data.i_raw_tx = initiate_raw_tx # TODO: Raw Transaction Validation
selected_swap_data.i_addr = receive_address # TODO: Receive Address Validation
selected_swap_data.i_token_hash = hashed_token
Expand Down Expand Up @@ -335,7 +342,7 @@ async def get_initiator_info(item: TokenItem, commons: DBCommons = Depends(db_co


@api.post("/participate_swap/")
async def participate_swap(item: TokenAndTxItem, commons: DBCommons = Depends(db_commons)) -> JSONResponse:
async def participate_swap(item: TokenAndTxAndContractItem, commons: DBCommons = Depends(db_commons)) -> JSONResponse:
token = item.token
status_code = status.HTTP_200_OK

Expand All @@ -346,9 +353,11 @@ async def participate_swap(item: TokenAndTxItem, commons: DBCommons = Depends(db
)

if result is None:
contract = item.contract
participate_raw_tx = item.rawTransaction

swap_data.swap_status = SwapStatus.PARTICIPATED
swap_data.p_contract = contract
swap_data.p_raw_tx = participate_raw_tx # TODO: Raw Transaction Validation

result = commons.update_swap(hashed_token, swap_data)
Expand Down
2 changes: 1 addition & 1 deletion asns/coins/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from . import *
from .base import CoinBaseData
43 changes: 42 additions & 1 deletion asns/coins/base.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,57 @@
# Copyright (c) 2020 The Atomic Swap Network Developers
# Licensed under the GNU General Public License, Version 3.

import json

from dataclasses import dataclass
from typing import List, Dict
from typing import List, Dict, Tuple

from ..util import resource_path


@dataclass
class CoinBaseData:
name: str = None
symbol: str = None
insight: List[str] = None
blockbook: List[str] = None
electrumx: Dict = None
p2pkh_prefix: bytes = None
p2sh_prefix: bytes = None
bech32_prefix: str = None

@classmethod
def from_json(cls, coin_name: str) -> 'CoinBaseData':
low = coin_name.lower()
if "Testnet" in coin_name:
low, testnet = low.split()
with open(resource_path("coins", low + "_" + testnet + ".json")) as f:
coin_json = json.loads(f.read())
else:
with open(resource_path("coins", low + ".json")) as f:
coin_json = json.loads(f.read())

shaped_data = {}

data_list: List[Tuple[str, type]] = [
("name", str),
("symbol", str),
("insight", list),
("blockbook", list),
("electrumx", dict),
("p2pkh_prefix", int),
("p2sh_prefix", int),
("bech32_prefix", str)
]

for d in data_list:
data = coin_json.get(d[0])
shaped_data[d[0]] = None if not isinstance(data, d[1]) else data
if shaped_data[d[0]] is not None and d[0].endswith("prefix") and d[1] == int:
try:
shaped_data[d[0]] = bytes([data])
except Exception:
pass

return CoinBaseData(**shaped_data)

25 changes: 25 additions & 0 deletions asns/coins/bitcoin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "Bitcoin",
"symbol": "BTC",
"insight": [
"https://api.bitcore.io/api/BTC/mainnet/"
],
"blockbook": [
"https://btc1.trezor.io/api/",
"https://btc2.trezor.io/api/",
"https://btc3.trezor.io/api/"
],
"electrumx": {
"electrum.blockstream.info": {
"s": 50002,
"t": 50001
},
"b.1209k.com": {
"s": 50002,
"t": 50001
}
},
"p2pkh_prefix": 0,
"p2sh_prefix": 5,
"bech32_prefix": "bc"
}
11 changes: 0 additions & 11 deletions asns/coins/bitcoin.py

This file was deleted.

4 changes: 4 additions & 0 deletions asns/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,13 @@ class TxDBData:
i_receive_amount: int = None
i_addr: str = None
i_token_hash: bytes = None
i_contract: str = None
i_raw_tx: str = None
i_redeem_raw_tx: str = None
p_currency: str = None # TODO: Make Currency Dataclass
p_receive_amount: int = None
p_addr: str = None
p_contract: str = None
p_raw_tx: str = None
p_redeem_raw_tx: str = None
swap_status: SwapStatus = SwapStatus.REGISTERED
Expand All @@ -55,11 +57,13 @@ def from_dict(cls, dict_data: Dict) -> 'TxDBData':
("i_receive_amount", int),
("i_addr", str),
("i_token_hash", bytes),
("i_contract", str),
("i_raw_tx", str),
("i_redeem_raw_tx", str),
("p_currency", str),
("p_receive_amount", int),
("p_addr", str),
("p_contract", str),
("p_raw_tx", str),
("p_redeem_raw_tx", str),
("swap_status", int)
Expand Down
13 changes: 13 additions & 0 deletions asns/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
from typing import Union

os_name = platform.system()
pkg_dir = os.path.split(os.path.realpath(__file__))[0]


def resource_path(*parts):
return os.path.join(pkg_dir, *parts)


def get_path() -> str:
Expand Down Expand Up @@ -53,6 +58,14 @@ def sha256d(x: Union[bytes, str]) -> bytes:
return bytes(sha256(sha256(x)))


def hash160(x: Union[bytes, str]) -> bytes:
x = to_bytes(x, "utf8")
h160 = hashlib.new("ripemd160")
h160.update(sha256(x))
out = h160.digest()
return bytes(out)


class ErrorMessages(Enum):
TOKEN_INVALID = "Token is not registered or is invalid."
TOKEN_STATUS_INVALID = "Inappropriate token status."
Expand Down

0 comments on commit ebd0825

Please sign in to comment.