Skip to content

Commit 2ce9953

Browse files
authored
[FEAT] 사용자 정보 조회 (NFT 조회 제외) (#20)
## 작업 내역 (관련 이슈) - #19 ## 특이 사항 -
2 parents fa233de + 8a3f57f commit 2ce9953

5 files changed

Lines changed: 162 additions & 19 deletions

File tree

.aws/ecs-task-definition.json

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,31 +18,23 @@
1818
{
1919
"name": "ENV",
2020
"value": "prod"
21+
},
22+
{
23+
"name": "AWS_REGION",
24+
"value": "ap-northeast-2"
2125
}
2226
],
2327
"environmentFiles": [],
2428
"mountPoints": [],
2529
"volumesFrom": [],
2630
"secrets": [
2731
{
28-
"name": "MONGODB_URI",
29-
"valueFrom": "arn:aws:ssm:ap-northeast-2:864981757354:parameter/xrpedia/documentdb/host"
30-
},
31-
{
32-
"name": "MONGODB_PORT",
33-
"valueFrom": "arn:aws:ssm:ap-northeast-2:864981757354:parameter/xrpedia/documentdb/port"
34-
},
35-
{
36-
"name": "MONGODB_DB",
37-
"valueFrom": "arn:aws:ssm:ap-northeast-2:864981757354:parameter/xrpedia/documentdb/dbname"
38-
},
39-
{
40-
"name": "MONGODB_USER",
41-
"valueFrom": "arn:aws:secretsmanager:ap-northeast-2:864981757354:secret:rds!cluster-b06771f3-3e07-4b6c-8e7b-b793cb7b498e-CcZIQG:username::"
32+
"name": "MONGODB_URL",
33+
"valueFrom": "arn:aws:secretsmanager:ap-northeast-2:864981757354:secret:xrpedia/credentials-UAy9x0:xrpedia-mongodb-url::"
4234
},
4335
{
44-
"name": "MONGODB_PASSWORD",
45-
"valueFrom": "arn:aws:secretsmanager:ap-northeast-2:864981757354:secret:rds!cluster-b06771f3-3e07-4b6c-8e7b-b793cb7b498e-CcZIQG:password::"
36+
"name": "COGNITO_USER_POOL_ID",
37+
"valueFrom": "arn:aws:secretsmanager:ap-northeast-2:864981757354:secret:xrpedia/credentials-UAy9x0:xrpedia-cognito-user-pool-id::"
4638
}
4739
],
4840
"ulimits": [],

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,4 +173,5 @@ cython_debug/
173173
# PyPI configuration file
174174
.pypirc
175175

176-
.DS_Store
176+
.DS_Store
177+
.docs

src/main/users/dto/UserInfoDto.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from pydantic import BaseModel
2+
3+
class UserInfoResponse(BaseModel):
4+
user_id: str
5+
nickname: str
6+
level_title: str
7+
point: float
8+
total_revenue: float

src/main/users/router/UserAPIRouter.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import uuid
22
from fastapi import APIRouter, Depends
33
from src.main.auth.dependencies import get_current_user
4+
from src.main.users.dto.UserInfoDto import UserInfoResponse
45
from src.main.users.service.UserService import UserService
56

67
router = APIRouter(
@@ -22,4 +23,11 @@ async def create_wallet(
2223
user_id: uuid.UUID = Depends(get_current_user),
2324
user_service: UserService = Depends()
2425
):
25-
return await user_service.generate_wallet(str(user_id))
26+
return await user_service.generate_wallet(str(user_id))
27+
28+
@router.get("", response_model=UserInfoResponse)
29+
async def get_user_info(
30+
user_id: uuid.UUID = Depends(get_current_user),
31+
user_service: UserService = Depends()
32+
):
33+
return user_service.get_user_info(str(user_id))

src/main/users/service/UserService.py

Lines changed: 135 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,32 @@
11
from xrpl.clients import JsonRpcClient
22
from xrpl.asyncio.wallet import generate_faucet_wallet
3+
from xrpl.models.requests import AccountInfo, AccountTx
4+
from xrpl.utils import xrp_to_drops
35
from src.main.users.repository.UserRepository import UserRepository
6+
import boto3
7+
import os
8+
from src.main.users.dto.UserInfoDto import UserInfoResponse
9+
from dotenv import load_dotenv
10+
11+
load_dotenv()
412

513
TESTNET_URL = "https://s.altnet.rippletest.net:51234"
614
client = JsonRpcClient(TESTNET_URL)
715
class UserService:
816
def __init__(self):
917
self.user_repository = UserRepository()
18+
if os.environ.get('ENV') == 'local-profile':
19+
self.cognito_client = boto3.client(
20+
'cognito-idp',
21+
region_name=os.environ.get('AWS_REGION', 'ap-northeast-2'),
22+
profile_name=os.environ.get('AWS_PROFILE', 'default')
23+
)
24+
else:
25+
self.cognito_client = boto3.client(
26+
'cognito-idp',
27+
region_name=os.environ.get('AWS_REGION', 'ap-northeast-2')
28+
)
29+
self.user_pool_id = os.environ.get('COGNITO_USER_POOL_ID', '')
1030

1131
def get_wallets(self, user_id: str):
1232
wallets = self.user_repository.find_wallets_by_user_id(user_id)
@@ -18,4 +38,118 @@ async def generate_wallet(self, user_id: str):
1838
wallet = await generate_faucet_wallet(client=client, debug=True)
1939
wallet_address = wallet.classic_address
2040
result = self.user_repository.save_wallet(user_id, wallet_address)
21-
return result
41+
return result
42+
43+
def get_account_info(self, client: JsonRpcClient, address: str, **kwargs) -> dict:
44+
"""
45+
XRPL 네트워크에서 이 계정의 정보를 가져옵니다.
46+
47+
Args:
48+
client (JsonRpcClient): 요청을 보낼 클라이언트입니다.
49+
address (str): 계정 정보를 조회할 계정의 주소입니다.
50+
**kwargs: 추가적인 선택적 매개변수들입니다.
51+
52+
Returns:
53+
dict: 이 계정의 정보를 포함하는 딕셔너리 객체입니다.
54+
"""
55+
return client.request(AccountInfo(account=address, **kwargs))
56+
57+
def get_account_transactions(self, client: JsonRpcClient, address: str, limit: int = 0, **kwargs) -> list:
58+
"""
59+
XRPL 네트워크에서 이 계정의 거래 내역을 가져옵니다.
60+
61+
Args:
62+
client (JsonRpcClient): 요청을 보낼 클라이언트입니다.
63+
address (str): 거래 내역을 조회할 계정의 주소입니다.
64+
limit (Optional[int]): 검색할 거래의 최대 개수입니다. 0이면 모두 검색합니다. 기본값은 0입니다.
65+
**kwargs: 추가적인 선택적 매개변수들입니다.
66+
67+
Returns:
68+
list: 이 계정의 거래 내역을 포함하는 리스트입니다.
69+
"""
70+
result = client.request(AccountTx(account=address, limit=limit, **kwargs))
71+
return result.get('result', {}).get('transactions', [])
72+
73+
def get_user_info(self, user_id: str) -> UserInfoResponse:
74+
# Cognito에서 nickname 조회
75+
nickname = "Unknown"
76+
try:
77+
if self.user_pool_id:
78+
# Cognito 사용자 풀에서 사용자 정보 조회
79+
response = self.cognito_client.list_users(
80+
UserPoolId=self.user_pool_id,
81+
Filter=f'sub = "{user_id}"'
82+
)
83+
84+
if response.get('Users') and len(response['Users']) > 0:
85+
# 사용자의 속성에서 nickname 찾기
86+
for attr in response['Users'][0].get('Attributes', []):
87+
if attr['Name'] == 'nickname':
88+
nickname = attr['Value']
89+
break
90+
except Exception as e:
91+
print(f"Error fetching user from Cognito: {str(e)}")
92+
93+
# MongoDB에서 사용자의 지갑 주소 조회
94+
# point = 0.0
95+
# total_revenue = 0.0
96+
# wallets = self.user_repository.find_wallets_by_user_id(user_id)
97+
# if wallets:
98+
# try:
99+
# # 첫 번째 지갑의 잔액 조회
100+
# wallet_address = wallets[0].get('address')
101+
# if wallet_address:
102+
# # XRPL 네트워크에서 계정 정보 조회
103+
# account_info = self.get_account_info(client, wallet_address)
104+
# if account_info and 'result' in account_info:
105+
# # 잔액 정보 추출
106+
# balance = account_info['result'].get('account_data', {}).get('Balance', '0')
107+
# # XRP 단위로 변환 (XRP는 소수점 6자리까지 표현)
108+
# point = float(balance) / 1000000
109+
110+
# # 계정의 거래 내역 조회
111+
# transactions = self.get_account_transactions(client, wallet_address)
112+
113+
# # 사용자가 받은 모든 금액 합산 (수익)
114+
# for tx in transactions:
115+
# # 트랜잭션이 '지불' 타입이고, 이 지갑이 수취인인 경우
116+
# if (tx.get('tx', {}).get('TransactionType') == 'Payment' and
117+
# tx.get('tx', {}).get('Destination') == wallet_address):
118+
# # 지불된 금액 추출 (delivered_amount 또는 Amount 사용)
119+
# delivered_amount = tx.get('meta', {}).get('delivered_amount')
120+
# amount = tx.get('tx', {}).get('Amount')
121+
122+
# # 실제 받은 금액 계산
123+
# received_amount = 0
124+
# if delivered_amount and isinstance(delivered_amount, str):
125+
# received_amount = float(delivered_amount) / 1000000
126+
# elif amount and isinstance(amount, str):
127+
# received_amount = float(amount) / 1000000
128+
129+
# total_revenue += received_amount
130+
131+
# except Exception as e:
132+
# print(f"Error fetching data from XRPL: {str(e)}")
133+
134+
# nft_grade, point, total_revenue 조회 -> 모두 `wallets` 컬렉션에서 조회
135+
total_revenue = 0.0
136+
point = 0.0
137+
nft_grade = "조회되지 않음"
138+
139+
wallets = self.user_repository.find_wallets_by_user_id(user_id)
140+
if wallets:
141+
for wallet in wallets:
142+
total_revenue += wallet.get('total_revenue', 0.0)
143+
point += wallet.get('point', 0.0)
144+
nft_grade = wallet.get('nft_grade', "조회되지 않음")
145+
146+
# 응답 객체 생성 및 반환
147+
user_info = UserInfoResponse(
148+
user_id=user_id,
149+
nickname=nickname,
150+
level_title=nft_grade,
151+
point=point, # XRPL 계정 잔액으로 설정
152+
total_revenue=total_revenue # 계산된 총 수익
153+
)
154+
155+
return user_info

0 commit comments

Comments
 (0)