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

feat: Added locked balance #454

Merged
merged 2 commits into from
Jan 6, 2023
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
3 changes: 2 additions & 1 deletion app/model/db/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@
from .idx_position import (
IDXPosition,
IDXPositionBondBlockNumber,
IDXPositionShareBlockNumber
IDXPositionShareBlockNumber,
IDXLockedPosition
)
from .idx_personal_info import (
IDXPersonalInfo,
Expand Down
22 changes: 22 additions & 0 deletions app/model/db/idx_position.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,25 @@ class IDXPositionShareBlockNumber(Base):
id = Column(BigInteger, primary_key=True, autoincrement=True)
# latest blockNumber
latest_block_number = Column(BigInteger)


class IDXLockedPosition(Base):
"""INDEX Locked Position"""
__tablename__ = "idx_locked_position"

# token address
token_address = Column(String(42), primary_key=True)
# lock address
lock_address = Column(String(42), primary_key=True)
# account address
account_address = Column(String(42), primary_key=True)
# locked amount
value = Column(BigInteger, nullable=False)

def json(self):
return {
"token_address": self.token_address,
"lock_address": self.lock_address,
"account_address": self.account_address,
"value": self.value
}
1 change: 1 addition & 0 deletions app/model/schema/holder.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class HolderResponse(BaseModel):
exchange_balance: int
exchange_commitment: int
pending_transfer: int
locked: int


class HolderCountResponse(BaseModel):
Expand Down
1 change: 1 addition & 0 deletions app/model/schema/position.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class PositionResponse(BaseModel):
exchange_balance: int
exchange_commitment: int
pending_transfer: int
locked: int


class ListAllPositionResponse(BaseModel):
Expand Down
66 changes: 47 additions & 19 deletions app/routers/bond.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
TokenType,
UpdateToken,
IDXPosition,
IDXLockedPosition,
IDXPersonalInfo,
BulkTransfer,
BulkTransferUpload,
Expand Down Expand Up @@ -1324,16 +1325,25 @@ def list_all_holders(
if _token.token_status == 0:
raise InvalidParameterError("this token is temporarily unavailable")

query = db.query(IDXPosition). \
filter(IDXPosition.token_address == token_address)
# Get Holders
query = db.query(IDXPosition, func.sum(IDXLockedPosition.value)). \
outerjoin(
IDXLockedPosition,
and_(IDXLockedPosition.token_address == IDXPosition.token_address,
IDXLockedPosition.account_address == IDXPosition.account_address)
). \
filter(IDXPosition.token_address == token_address).\
group_by(IDXPosition.id, IDXLockedPosition.token_address, IDXLockedPosition.account_address)

if not include_former_holder:
# Get Holders
query = query.filter(or_(
IDXPosition.balance != 0,
IDXPosition.exchange_balance != 0,
IDXPosition.pending_transfer != 0,
IDXPosition.exchange_commitment != 0
IDXPosition.exchange_commitment != 0,
IDXLockedPosition.value != 0
))

_holders = query.order_by(IDXPosition.id).all()

# Get personal information
Expand All @@ -1357,18 +1367,19 @@ def list_all_holders(
}

holders = []
for _holder in _holders:
for _position, _locked in _holders:
_personal_info = _personal_info_dict.get(
_holder.account_address,
_position.account_address,
personal_info_default
)
holders.append({
"account_address": _holder.account_address,
"account_address": _position.account_address,
"personal_information": _personal_info,
"balance": _holder.balance,
"exchange_balance": _holder.exchange_balance,
"exchange_commitment": _holder.exchange_commitment,
"pending_transfer": _holder.pending_transfer
"balance": _position.balance,
"exchange_balance": _position.exchange_balance,
"exchange_commitment": _position.exchange_commitment,
"pending_transfer": _position.pending_transfer,
"locked": _locked if _locked is not None else 0
})

return json_response(holders)
Expand Down Expand Up @@ -1409,14 +1420,21 @@ def count_number_of_holders(
raise InvalidParameterError("this token is temporarily unavailable")

# Get Holders
_count: int = db.query(IDXPosition). \
_count: int = db.query(IDXPosition, func.sum(IDXLockedPosition.value)). \
outerjoin(
IDXLockedPosition,
and_(IDXLockedPosition.token_address == IDXPosition.token_address,
IDXLockedPosition.account_address == IDXPosition.account_address)
). \
filter(IDXPosition.token_address == token_address). \
filter(
or_(IDXPosition.balance != 0,
IDXPosition.exchange_balance != 0,
IDXPosition.pending_transfer != 0,
IDXPosition.exchange_commitment != 0)
IDXPosition.exchange_commitment != 0,
IDXLockedPosition.value != 0)
). \
group_by(IDXPosition.id, IDXLockedPosition.token_address, IDXLockedPosition.account_address). \
count()

return json_response({
Expand Down Expand Up @@ -1460,20 +1478,29 @@ def retrieve_holder(
raise InvalidParameterError("this token is temporarily unavailable")

# Get Holders
_holder = db.query(IDXPosition). \
_holder = db.query(IDXPosition, func.sum(IDXLockedPosition.value)). \
outerjoin(
IDXLockedPosition,
and_(IDXLockedPosition.token_address == IDXPosition.token_address,
IDXLockedPosition.account_address == IDXPosition.account_address)
). \
filter(IDXPosition.token_address == token_address). \
filter(IDXPosition.account_address == account_address). \
group_by(IDXPosition.id, IDXLockedPosition.token_address, IDXLockedPosition.account_address). \
first()

if _holder is None:
balance = 0
exchange_balance = 0
exchange_commitment = 0
pending_transfer = 0
locked = 0
else:
balance = _holder.balance
exchange_balance = _holder.exchange_balance
exchange_commitment = _holder.exchange_commitment
pending_transfer = _holder.pending_transfer
balance = _holder[0].balance
exchange_balance = _holder[0].exchange_balance
exchange_commitment = _holder[0].exchange_commitment
pending_transfer = _holder[0].pending_transfer
locked = _holder[1]

# Get personal information
personal_info_default = {
Expand Down Expand Up @@ -1501,7 +1528,8 @@ def retrieve_holder(
"balance": balance,
"exchange_balance": exchange_balance,
"exchange_commitment": exchange_commitment,
"pending_transfer": pending_transfer
"pending_transfer": pending_transfer,
"locked": locked if locked is not None else 0
}

return json_response(holder)
Expand Down
43 changes: 36 additions & 7 deletions app/routers/position.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
Query
)
from fastapi.exceptions import HTTPException
from sqlalchemy import or_
from sqlalchemy import or_, func, and_
from sqlalchemy.orm import Session

from app.database import db_session
Expand All @@ -41,6 +41,7 @@
)
from app.model.db import (
IDXPosition,
IDXLockedPosition,
Token,
TokenType
)
Expand Down Expand Up @@ -73,17 +74,24 @@ def list_all_position(
validate_headers(issuer_address=(issuer_address, address_is_valid_address))

# Get a list of positions
query = db.query(IDXPosition, Token). \
query = db.query(IDXPosition, func.sum(IDXLockedPosition.value), Token). \
join(Token, IDXPosition.token_address == Token.token_address). \
outerjoin(
IDXLockedPosition,
and_(IDXLockedPosition.token_address == IDXPosition.token_address,
IDXLockedPosition.account_address == IDXPosition.account_address)
). \
filter(IDXPosition.account_address == account_address). \
filter(Token.token_status != 2)
filter(Token.token_status != 2). \
group_by(IDXPosition.id, Token.id, IDXLockedPosition.token_address, IDXLockedPosition.account_address)

if not include_former_position:
query = query.filter(or_(
IDXPosition.balance != 0,
IDXPosition.exchange_balance != 0,
IDXPosition.pending_transfer != 0,
IDXPosition.exchange_commitment != 0
IDXPosition.exchange_commitment != 0,
IDXLockedPosition.value != 0
))

query = query.order_by(IDXPosition.token_address, IDXPosition.account_address)
Expand All @@ -106,7 +114,7 @@ def list_all_position(
_position_list = query.all()

positions = []
for _position, _token in _position_list:
for _position, _locked, _token in _position_list:
# Get Token Name
token_name = None
if _token.type == TokenType.IBET_STRAIGHT_BOND.value:
Expand All @@ -124,6 +132,7 @@ def list_all_position(
"exchange_balance": _position.exchange_balance,
"exchange_commitment": _position.exchange_commitment,
"pending_transfer": _position.pending_transfer,
"locked": _locked if _locked is not None else 0
})

resp = {
Expand Down Expand Up @@ -168,13 +177,32 @@ def retrieve_position(
raise InvalidParameterError("this token is temporarily unavailable")

# Get Position
_position = db.query(IDXPosition). \
_record = db.query(IDXPosition, func.sum(IDXLockedPosition.value)). \
outerjoin(
IDXLockedPosition,
and_(IDXLockedPosition.token_address == IDXPosition.token_address,
IDXLockedPosition.account_address == IDXPosition.account_address)
). \
filter(IDXPosition.token_address == token_address). \
filter(IDXPosition.account_address == account_address). \
group_by(IDXPosition.id, IDXLockedPosition.token_address, IDXLockedPosition.account_address). \
first()

if _record is not None:
_position = _record[0]
_locked = _record[1]
else:
_position = None
_locked = None

if _position is None:
# If there is no position, set default value(0) to each balance.
_position = IDXPosition(balance=0, exchange_balance=0, exchange_commitment=0, pending_transfer=0)
_position = IDXPosition(
balance=0,
exchange_balance=0,
exchange_commitment=0,
pending_transfer=0
)

# Get Token Name
token_name = None
Expand All @@ -194,6 +222,7 @@ def retrieve_position(
"exchange_balance": _position.exchange_balance,
"exchange_commitment": _position.exchange_commitment,
"pending_transfer": _position.pending_transfer,
"locked": _locked if _locked is not None else 0
}

return json_response(resp)
Loading