Skip to content
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
4 changes: 4 additions & 0 deletions .aws/ecs-task-definition.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@
{
"name": "AWS_S3_BUCKET_NAME",
"valueFrom": "arn:aws:secretsmanager:ap-northeast-2:864981757354:secret:xrpedia/credentials-UAy9x0:xrpedia-s3-bucket-name::"
},
{
"name": "COGNITO_USER_POOL_ID",
"valueFrom": "arn:aws:secretsmanager:ap-northeast-2:864981757354:secret:xrpedia/credentials-UAy9x0:xrpedia-cognito-user-pool-id::"
}
],
"ulimits": [],
Expand Down
2 changes: 1 addition & 1 deletion src/main/document/dto/document.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class saveDocument(BaseModel):
downloads: int # 더미
pageNumber: int # 더미
upload_date: datetime
uploader_id: str
uploader: str
price: float
category: str
rating: float # 더미
Expand Down
6 changes: 3 additions & 3 deletions src/main/document/repository/document_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def get_document(document_id: str) -> documentDetailDto:
downloads= get_doc["downloads"],
pageNumber= int(get_doc["pageNumber"], 0),
upload_date= get_doc["upload_date"],
uploader= get_doc["uploader_id"], #이거 추후에 변경해야 함함
uploader= get_doc["uploader"], #이거 추후에 변경해야 함함
price= get_doc["price"],
category= get_doc["category"],
rating= get_doc["rating"])
Expand All @@ -59,7 +59,7 @@ def get_documents_by_user(user_id: str) -> List[documentDetailDto]:
downloads=doc["downloads"],
pageNumber=doc["pageNumber"],
upload_date=doc["upload_date"],
uploader=doc["uploader_id"],
uploader=doc["uploader"],
price=doc["price"],
category=doc["category"],
rating=doc["rating"]
Expand Down Expand Up @@ -94,7 +94,7 @@ def get_all_documents():
downloads=doc["downloads"],
pageNumber=doc["pageNumber"],
upload_date=doc["upload_date"],
uploader=doc["uploader_id"],
uploader=doc["uploader"],
price=doc["price"],
category=doc["category"],
rating=doc["rating"]
Expand Down
6 changes: 5 additions & 1 deletion src/main/document/service/document_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from src.main.user.repository.UserRepository import get_user
from src.main.nft.service.nft_service import process_nft_issuance_with_response
from src.main.document.dto.document import saveDocument, documentRequestDto
from src.main.user.service import UserService
from datetime import datetime
import asyncio

Expand All @@ -14,6 +15,9 @@
async def save_document_service(request: documentRequestDto, user_id: str) :
upload_date = datetime.now()

user = UserService.get_user_info(user_id)
user_name = user["nickname"]

saved = saveDocument(
file_id = request.file_id,
document_name = request.document_name,
Expand All @@ -22,7 +26,7 @@ async def save_document_service(request: documentRequestDto, user_id: str) :
downloads=32,
pageNumber=3,
upload_date=upload_date,
uploader_id=user_id,
uploader=user_name,
price=request.price,
category=request.category,
rating=4.0
Expand Down
8 changes: 8 additions & 0 deletions src/main/user/dto/UserInfoDto.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from pydantic import BaseModel

class UserInfoResponse(BaseModel):
user_id: str
nickname: str
level_title: str
point: float
total_revenue: float
62 changes: 50 additions & 12 deletions src/main/user/repository/UserRepository.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,59 @@
from src.config.mongodb import get_mongo_client

from typing import Optional
from src.config.mongodb import get_mongo_client

class UserRepository:
def __init__(self):
client = get_mongo_client()
self.db = client["xrpedia-data"]
self.wallets_collection = self.db["wallets"]

def find_wallets_by_user_id(self, user_id: str) -> list:
wallets = list(self.wallets_collection.find({"user_id": user_id}, {"_id": 0}))
return wallets if wallets else []

def save_wallet(self, user_id: str, wallet_address: str, point: int = 0, nft_grade: str = "bronze"):
existing = self.wallets_collection.find_one({"user_id": user_id})
if existing:
self.wallets_collection.update_one(
{"user_id": user_id},
{"$set": {"address": wallet_address,
"point": point,
"nft_grade": nft_grade}}
)
return {"message": "Wallet updated",
"user_id": user_id,
"wallet_address": wallet_address,
"point": point,
"nft_grade": nft_grade}
else:
self.wallets_collection.insert_one({"user_id": user_id,
"address": wallet_address,
"point": point,
"nft_grade": nft_grade})
return {"message": "Wallet created",
"user_id": user_id,
"wallet_address": wallet_address,
"point": point,
"nft_grade": nft_grade}

#db에서 user 가져오기
def get_user(user_id: str) -> str:
client = get_mongo_client()
db = client['xrpedia-data']
nft_collection = db['wallets']
def get_user(user_id: str) -> str:
client = get_mongo_client()
db = client['xrpedia-data']
nft_collection = db['wallets']

if not user_id:
raise Exception(404, detail="회원 정보를 찾을 수 없습니다.")
if not user_id:
raise Exception(404, detail="회원 정보를 찾을 수 없습니다.")


user = nft_collection.find_one({"user_id": user_id})
user = nft_collection.find_one({"user_id": user_id})

if not user:
raise Exception(404, detail="해당 유저를 찾을 수 없습니다.")
if not user:
raise Exception(404, detail="해당 유저를 찾을 수 없습니다.")

# ObjectId는 JSON 직렬화가 안 되므로 필요 시 string으로 바꿔줍니다
user["_id"] = str(user["_id"])
# ObjectId는 JSON 직렬화가 안 되므로 필요 시 string으로 바꿔줍니다
user["_id"] = str(user["_id"])

return user
return user
157 changes: 157 additions & 0 deletions src/main/user/service/UserService.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
from xrpl.clients import JsonRpcClient
from xrpl.asyncio.wallet import generate_faucet_wallet
from xrpl.models.requests import AccountInfo, AccountTx
from xrpl.utils import xrp_to_drops
from src.main.user.repository.UserRepository import UserRepository
import boto3
import os
from src.main.user.dto.UserInfoDto import UserInfoResponse
from dotenv import load_dotenv

load_dotenv()

TESTNET_URL = "https://s.altnet.rippletest.net:51234"
client = JsonRpcClient(TESTNET_URL)
class UserService:
def __init__(self):
self.user_repository = UserRepository()
self.user_pool_id = os.environ.get('COGNITO_USER_POOL_ID', '')
if os.environ.get('ENV') == 'local-profile':
session = boto3.Session(
profile_name=os.environ.get('AWS_PROFILE', 'default')
)
self.cognito_client = session.client(
'cognito-idp',
region_name=os.environ.get('AWS_REGION', 'ap-northeast-2')
)
else:
self.cognito_client = boto3.client(
'cognito-idp',
region_name=os.environ.get('AWS_REGION', 'ap-northeast-2')
)

def get_wallets(self, user_id: str):
wallets = self.user_repository.find_wallets_by_user_id(user_id)
if not wallets:
return {"message": "No wallets found for this user"}
return wallets

async def generate_wallet(self, user_id: str):
wallet = await generate_faucet_wallet(client=client, debug=True)
wallet_address = wallet.classic_address
result = self.user_repository.save_wallet(user_id, wallet_address)
return result

def get_account_info(self, client: JsonRpcClient, address: str, **kwargs) -> dict:
"""
XRPL 네트워크에서 이 계정의 정보를 가져옵니다.

Args:
client (JsonRpcClient): 요청을 보낼 클라이언트입니다.
address (str): 계정 정보를 조회할 계정의 주소입니다.
**kwargs: 추가적인 선택적 매개변수들입니다.

Returns:
dict: 이 계정의 정보를 포함하는 딕셔너리 객체입니다.
"""
return client.request(AccountInfo(account=address, **kwargs))

def get_account_transactions(self, client: JsonRpcClient, address: str, limit: int = 0, **kwargs) -> list:
"""
XRPL 네트워크에서 이 계정의 거래 내역을 가져옵니다.

Args:
client (JsonRpcClient): 요청을 보낼 클라이언트입니다.
address (str): 거래 내역을 조회할 계정의 주소입니다.
limit (Optional[int]): 검색할 거래의 최대 개수입니다. 0이면 모두 검색합니다. 기본값은 0입니다.
**kwargs: 추가적인 선택적 매개변수들입니다.

Returns:
list: 이 계정의 거래 내역을 포함하는 리스트입니다.
"""
result = client.request(AccountTx(account=address, limit=limit, **kwargs))
return result.get('result', {}).get('transactions', [])

def get_user_info(self, user_id: str) -> UserInfoResponse:
# Cognito에서 nickname 조회
nickname = "Unknown"
try:
if self.user_pool_id:
# Cognito 사용자 풀에서 사용자 정보 조회
response = self.cognito_client.list_users(
UserPoolId=self.user_pool_id,
Filter=f'sub = "{user_id}"'
)

if response.get('Users') and len(response['Users']) > 0:
# 사용자의 속성에서 nickname 찾기
for attr in response['Users'][0].get('Attributes', []):
if attr['Name'] == 'nickname':
nickname = attr['Value']
break
except Exception as e:
print(f"Error fetching user from Cognito: {str(e)}")

# MongoDB에서 사용자의 지갑 주소 조회
# point = 0.0
# total_revenue = 0.0
# wallets = self.user_repository.find_wallets_by_user_id(user_id)
# if wallets:
# try:
# # 첫 번째 지갑의 잔액 조회
# wallet_address = wallets[0].get('address')
# if wallet_address:
# # XRPL 네트워크에서 계정 정보 조회
# account_info = self.get_account_info(client, wallet_address)
# if account_info and 'result' in account_info:
# # 잔액 정보 추출
# balance = account_info['result'].get('account_data', {}).get('Balance', '0')
# # XRP 단위로 변환 (XRP는 소수점 6자리까지 표현)
# point = float(balance) / 1000000

# # 계정의 거래 내역 조회
# transactions = self.get_account_transactions(client, wallet_address)

# # 사용자가 받은 모든 금액 합산 (수익)
# for tx in transactions:
# # 트랜잭션이 '지불' 타입이고, 이 지갑이 수취인인 경우
# if (tx.get('tx', {}).get('TransactionType') == 'Payment' and
# tx.get('tx', {}).get('Destination') == wallet_address):
# # 지불된 금액 추출 (delivered_amount 또는 Amount 사용)
# delivered_amount = tx.get('meta', {}).get('delivered_amount')
# amount = tx.get('tx', {}).get('Amount')

# # 실제 받은 금액 계산
# received_amount = 0
# if delivered_amount and isinstance(delivered_amount, str):
# received_amount = float(delivered_amount) / 1000000
# elif amount and isinstance(amount, str):
# received_amount = float(amount) / 1000000

# total_revenue += received_amount

# except Exception as e:
# print(f"Error fetching data from XRPL: {str(e)}")

# nft_grade, point, total_revenue 조회 -> 모두 `wallets` 컬렉션에서 조회
total_revenue = 0.0
point = 0.0
nft_grade = "조회되지 않음"

wallets = self.user_repository.find_wallets_by_user_id(user_id)
if wallets:
for wallet in wallets:
total_revenue += wallet.get('total_revenue', 0.0)
point += wallet.get('point', 0.0)
nft_grade = wallet.get('nft_grade', "조회되지 않음")

# 응답 객체 생성 및 반환
user_info = UserInfoResponse(
user_id=user_id,
nickname=nickname,
level_title=nft_grade,
point=point, # XRPL 계정 잔액으로 설정
total_revenue=total_revenue # 계산된 총 수익
)

return user_info
Loading