|
| 1 | +from xrpl.clients import JsonRpcClient |
| 2 | +from xrpl.asyncio.wallet import generate_faucet_wallet |
| 3 | +from xrpl.models.requests import AccountInfo, AccountTx |
| 4 | +from xrpl.utils import xrp_to_drops |
| 5 | +from src.main.user.repository.UserRepository import UserRepository |
| 6 | +import boto3 |
| 7 | +import os |
| 8 | +from src.main.user.dto.UserInfoDto import UserInfoResponse |
| 9 | +from dotenv import load_dotenv |
| 10 | + |
| 11 | +load_dotenv() |
| 12 | + |
| 13 | +TESTNET_URL = "https://s.altnet.rippletest.net:51234" |
| 14 | +client = JsonRpcClient(TESTNET_URL) |
| 15 | +class UserService: |
| 16 | + def __init__(self): |
| 17 | + self.user_repository = UserRepository() |
| 18 | + self.user_pool_id = os.environ.get('COGNITO_USER_POOL_ID', '') |
| 19 | + if os.environ.get('ENV') == 'local-profile': |
| 20 | + session = boto3.Session( |
| 21 | + profile_name=os.environ.get('AWS_PROFILE', 'default') |
| 22 | + ) |
| 23 | + self.cognito_client = session.client( |
| 24 | + 'cognito-idp', |
| 25 | + region_name=os.environ.get('AWS_REGION', 'ap-northeast-2') |
| 26 | + ) |
| 27 | + else: |
| 28 | + self.cognito_client = boto3.client( |
| 29 | + 'cognito-idp', |
| 30 | + region_name=os.environ.get('AWS_REGION', 'ap-northeast-2') |
| 31 | + ) |
| 32 | + |
| 33 | + def get_wallets(self, user_id: str): |
| 34 | + wallets = self.user_repository.find_wallets_by_user_id(user_id) |
| 35 | + if not wallets: |
| 36 | + return {"message": "No wallets found for this user"} |
| 37 | + return wallets |
| 38 | + |
| 39 | + async def generate_wallet(self, user_id: str): |
| 40 | + wallet = await generate_faucet_wallet(client=client, debug=True) |
| 41 | + wallet_address = wallet.classic_address |
| 42 | + result = self.user_repository.save_wallet(user_id, wallet_address) |
| 43 | + return result |
| 44 | + |
| 45 | + def get_account_info(self, client: JsonRpcClient, address: str, **kwargs) -> dict: |
| 46 | + """ |
| 47 | + XRPL 네트워크에서 이 계정의 정보를 가져옵니다. |
| 48 | +
|
| 49 | + Args: |
| 50 | + client (JsonRpcClient): 요청을 보낼 클라이언트입니다. |
| 51 | + address (str): 계정 정보를 조회할 계정의 주소입니다. |
| 52 | + **kwargs: 추가적인 선택적 매개변수들입니다. |
| 53 | +
|
| 54 | + Returns: |
| 55 | + dict: 이 계정의 정보를 포함하는 딕셔너리 객체입니다. |
| 56 | + """ |
| 57 | + return client.request(AccountInfo(account=address, **kwargs)) |
| 58 | + |
| 59 | + def get_account_transactions(self, client: JsonRpcClient, address: str, limit: int = 0, **kwargs) -> list: |
| 60 | + """ |
| 61 | + XRPL 네트워크에서 이 계정의 거래 내역을 가져옵니다. |
| 62 | +
|
| 63 | + Args: |
| 64 | + client (JsonRpcClient): 요청을 보낼 클라이언트입니다. |
| 65 | + address (str): 거래 내역을 조회할 계정의 주소입니다. |
| 66 | + limit (Optional[int]): 검색할 거래의 최대 개수입니다. 0이면 모두 검색합니다. 기본값은 0입니다. |
| 67 | + **kwargs: 추가적인 선택적 매개변수들입니다. |
| 68 | +
|
| 69 | + Returns: |
| 70 | + list: 이 계정의 거래 내역을 포함하는 리스트입니다. |
| 71 | + """ |
| 72 | + result = client.request(AccountTx(account=address, limit=limit, **kwargs)) |
| 73 | + return result.get('result', {}).get('transactions', []) |
| 74 | + |
| 75 | + def get_user_info(self, user_id: str) -> UserInfoResponse: |
| 76 | + # Cognito에서 nickname 조회 |
| 77 | + nickname = "Unknown" |
| 78 | + try: |
| 79 | + if self.user_pool_id: |
| 80 | + # Cognito 사용자 풀에서 사용자 정보 조회 |
| 81 | + response = self.cognito_client.list_users( |
| 82 | + UserPoolId=self.user_pool_id, |
| 83 | + Filter=f'sub = "{user_id}"' |
| 84 | + ) |
| 85 | + |
| 86 | + if response.get('Users') and len(response['Users']) > 0: |
| 87 | + # 사용자의 속성에서 nickname 찾기 |
| 88 | + for attr in response['Users'][0].get('Attributes', []): |
| 89 | + if attr['Name'] == 'nickname': |
| 90 | + nickname = attr['Value'] |
| 91 | + break |
| 92 | + except Exception as e: |
| 93 | + print(f"Error fetching user from Cognito: {str(e)}") |
| 94 | + |
| 95 | + # MongoDB에서 사용자의 지갑 주소 조회 |
| 96 | + # point = 0.0 |
| 97 | + # total_revenue = 0.0 |
| 98 | + # wallets = self.user_repository.find_wallets_by_user_id(user_id) |
| 99 | + # if wallets: |
| 100 | + # try: |
| 101 | + # # 첫 번째 지갑의 잔액 조회 |
| 102 | + # wallet_address = wallets[0].get('address') |
| 103 | + # if wallet_address: |
| 104 | + # # XRPL 네트워크에서 계정 정보 조회 |
| 105 | + # account_info = self.get_account_info(client, wallet_address) |
| 106 | + # if account_info and 'result' in account_info: |
| 107 | + # # 잔액 정보 추출 |
| 108 | + # balance = account_info['result'].get('account_data', {}).get('Balance', '0') |
| 109 | + # # XRP 단위로 변환 (XRP는 소수점 6자리까지 표현) |
| 110 | + # point = float(balance) / 1000000 |
| 111 | + |
| 112 | + # # 계정의 거래 내역 조회 |
| 113 | + # transactions = self.get_account_transactions(client, wallet_address) |
| 114 | + |
| 115 | + # # 사용자가 받은 모든 금액 합산 (수익) |
| 116 | + # for tx in transactions: |
| 117 | + # # 트랜잭션이 '지불' 타입이고, 이 지갑이 수취인인 경우 |
| 118 | + # if (tx.get('tx', {}).get('TransactionType') == 'Payment' and |
| 119 | + # tx.get('tx', {}).get('Destination') == wallet_address): |
| 120 | + # # 지불된 금액 추출 (delivered_amount 또는 Amount 사용) |
| 121 | + # delivered_amount = tx.get('meta', {}).get('delivered_amount') |
| 122 | + # amount = tx.get('tx', {}).get('Amount') |
| 123 | + |
| 124 | + # # 실제 받은 금액 계산 |
| 125 | + # received_amount = 0 |
| 126 | + # if delivered_amount and isinstance(delivered_amount, str): |
| 127 | + # received_amount = float(delivered_amount) / 1000000 |
| 128 | + # elif amount and isinstance(amount, str): |
| 129 | + # received_amount = float(amount) / 1000000 |
| 130 | + |
| 131 | + # total_revenue += received_amount |
| 132 | + |
| 133 | + # except Exception as e: |
| 134 | + # print(f"Error fetching data from XRPL: {str(e)}") |
| 135 | + |
| 136 | + # nft_grade, point, total_revenue 조회 -> 모두 `wallets` 컬렉션에서 조회 |
| 137 | + total_revenue = 0.0 |
| 138 | + point = 0.0 |
| 139 | + nft_grade = "조회되지 않음" |
| 140 | + |
| 141 | + wallets = self.user_repository.find_wallets_by_user_id(user_id) |
| 142 | + if wallets: |
| 143 | + for wallet in wallets: |
| 144 | + total_revenue += wallet.get('total_revenue', 0.0) |
| 145 | + point += wallet.get('point', 0.0) |
| 146 | + nft_grade = wallet.get('nft_grade', "조회되지 않음") |
| 147 | + |
| 148 | + # 응답 객체 생성 및 반환 |
| 149 | + user_info = UserInfoResponse( |
| 150 | + user_id=user_id, |
| 151 | + nickname=nickname, |
| 152 | + level_title=nft_grade, |
| 153 | + point=point, # XRPL 계정 잔액으로 설정 |
| 154 | + total_revenue=total_revenue # 계산된 총 수익 |
| 155 | + ) |
| 156 | + |
| 157 | + return user_info |
0 commit comments