Skip to content
This repository has been archived by the owner on Jul 20, 2024. It is now read-only.

Commit

Permalink
Support SEI/SEIYAN
Browse files Browse the repository at this point in the history
  • Loading branch information
wrkzdev committed Jan 29, 2024
1 parent 3f44682 commit e2ca6c8
Showing 1 changed file with 234 additions and 10 deletions.
244 changes: 234 additions & 10 deletions wrkzcoin_tipbot/cogs/wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,11 @@ async def cosmos_get_height(url: str, timeout: int=16):
await session.close()
decoded_data = json.loads(res_data)
if decoded_data is not None:
return int(decoded_data['result']['block']['header']['height'])
if decoded_data.get('result'):
return int(decoded_data['result']['block']['header']['height'])
elif decoded_data.get('block'):
# Some like SEI
return int(decoded_data['block']['header']['height'])
except asyncio.TimeoutError:
print('TIMEOUT: cosmos_get_height {} for {}s'.format(url, timeout))
except Exception as e:
Expand Down Expand Up @@ -3693,6 +3697,58 @@ async def cosmos_get_coin_by_denom(
traceback.print_exc(file=sys.stdout)
return None

async def cosmos_send_token_wasm(
self, proxy: str, rpc_url: str, coin_name: str, contract: str, priv_seed: str,
amount: float, coin_decimal: int, user_id: str, to_address: str, user_server: str,
withdraw_fee: float, memo: str = "", timeout: int=30
):
try:
data = {
"rpcEndpoint": rpc_url,
"recipient": to_address,
"amount": "{}".format(int(amount*10**coin_decimal)),
"contract": contract,
"mnemonic": priv_seed,
}
async with aiohttp.ClientSession() as session:
async with session.post(
proxy, json=data,
headers={'Content-Type': 'application/json'},
timeout=timeout
) as response:
if response.status == 200:
res_data = await response.read()
res_data = res_data.decode('utf-8')
await session.close()
decoded_data = json.loads(res_data)
if decoded_data is not None:
success = 1
try:
await self.openConnection()
async with self.pool.acquire() as conn:
async with conn.cursor() as cur:
sql = """
INSERT INTO `cosmos_external_tx`
(`coin_name`, `user_id`, `amount`, `tx_fee`, `withdraw_fee`,
`decimal`, `to_address`, `date`, `tx_hash`, `tx_dump`, `user_server`, `success`)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
"""
await cur.execute(sql, (
coin_name, user_id, amount, 0, withdraw_fee, coin_decimal,
to_address, int(time.time()), decoded_data['transactionHash'],
json.dumps(decoded_data), user_server, success
))
await conn.commit()
return decoded_data
except Exception:
await logchanbot("wallet cosmos_send_token_wasm " + str(traceback.format_exc()))
traceback.print_exc(file=sys.stdout)
except asyncio.TimeoutError:
print('TIMEOUT: cosmos_send_token_wasm {} for {}s'.format(rpc_url, timeout))
except Exception as e:
traceback.print_exc(file=sys.stdout)
return None

async def cosmos_send_tx(
self, rpc_url: str, chain_id: str, coin_name: str, account_num: int, sequence: int, priv_key: str,
amount: float, coin_decimal: int, user_id: str, to_address: str, user_server: str,
Expand Down Expand Up @@ -6790,6 +6846,31 @@ async def update_balance_cosmos(self):
return
await asyncio.sleep(time_lap)

# for custom token such as under sei
async def get_cosmos_token_transactions(ua: str, endpoint: str, account_addr: str, contract: str):
try:
headers = {
'Content-Type': 'application/json',
'User-Agent': ua
}
url = endpoint + "?pagination.limit=50&events=wasm._contract_address={}&events=wasm.to={}&order_by=ORDER_BY_DESC".format("%27" + contract + "%27", "%27" + account_addr + "%27")
async with aiohttp.ClientSession() as session:
async with session.get(
url,
headers=headers, timeout=60
) as response:
if response.status == 200:
res_data = await response.read()
res_data = res_data.decode('utf-8')
decoded_data = json.loads(res_data)
if len(decoded_data) > 0:
return decoded_data
else:
print("get_cosmos_token_transactions {} URL return: ".format(url, response.status))
except Exception:
traceback.print_exc(file=sys.stdout)
return []

async def get_cosmos_transactions(ua: str, endpoint: str, account_addr: str):
try:
headers = {
Expand Down Expand Up @@ -6851,6 +6932,107 @@ async def get_tx_incoming():
traceback.print_exc(file=sys.stdout)
return []

async def update_balance_cosmos_token(bot, main_token: str, token_name: str):
coin_family = "COSMOS"
timeout = 30
rpchost = getattr(getattr(bot.coin_list, main_token), "rpchost")
if not rpchost.endswith("/"):
rpchost += "/"
net_height = await cosmos_get_height(rpchost + "block", timeout)
# print("{}/{}, height {}".format(main_token, token_name, net_height))
if net_height is None:
print("cosmos cosmos_get_height: {} = None/{}".format(main_token, token_name))
return
else:
try:
await self.utils.async_set_cache_kv(
"block",
f"{bot.config['kv_db']['prefix'] + bot.config['kv_db']['daemon_height']}{token_name}",
net_height
)
# if there are other asset, set them all here
except Exception:
traceback.print_exc(file=sys.stdout)

try:
url = getattr(getattr(bot.coin_list, token_name), "http_address")
main_address = getattr(getattr(bot.coin_list, token_name), "MainAddress")
is_cosmwasm_token = getattr(getattr(bot.coin_list, token_name), "is_cosmwasm_token")
contract = getattr(getattr(bot.coin_list, token_name), "contract")
get_transactions = []
if is_cosmwasm_token == 0:
# wrong cosmwasm, it's not cosmwasm token
return
elif is_cosmwasm_token == 1:
get_transactions = await get_cosmos_token_transactions(
self.bot.config['discord']['default_browser_agent'], url, main_address, contract
)
if len(get_transactions) > 0:
get_incoming_tx = await get_tx_incoming()
list_existing_tx = []
if len(get_incoming_tx) > 0:
list_existing_tx = [each['txid'] for each in get_incoming_tx]
for each_tx in get_transactions['tx_responses']:
if each_tx['code'] != 0:
# skip
continue
try:
amount = 0.0
tx_hash = each_tx['txhash']
height = int(each_tx['height'])
if tx_hash in list_existing_tx:
# Skip
continue

user_id = None
user_memo = each_tx['tx']['body']['memo']
get_user_memo = None
if len(each_tx['tx']['body']['messages']) > 0:
for each_from_to in each_tx['tx']['body']['messages']:
if each_from_to.get('contract') and each_from_to['contract'] == contract and each_from_to.get('msg') :
try:
from_addr = each_from_to['sender']
to_addr = each_from_to['msg']['transfer']['recipient']
if to_addr != main_address:
# not to Bot
continue
if int(each_from_to['msg']['transfer']['amount']) > 0:
coin_decimal = getattr(getattr(bot.coin_list, token_name), "decimal")
amount = int(each_from_to['msg']['transfer']['amount']) / 10**coin_decimal

if user_memo and len(user_memo) > 0:
get_user_memo = await store.sql_get_userwallet_by_paymentid(
"{} MEMO: {}".format(main_address, user_memo),
token_name, coin_family
)
if get_user_memo is not None and get_user_memo['user_id'] is not None:
user_id = get_user_memo['user_id']

if amount > 0:
await self.openConnection()
async with self.pool.acquire() as conn:
async with conn.cursor() as cur:
sql = """
INSERT INTO `cosmos_get_transfers`
(`coin_name`, `user_id`, `txid`, `height`, `amount`,
`decimal`, `address`, `memo`, `time_insert`, `user_server`)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
"""
await cur.execute(sql, (
token_name, user_id, tx_hash, height, amount,
coin_decimal, main_address,
user_memo if user_memo else None,
int(time.time()),
get_user_memo['user_server'] if get_user_memo else None
))
await conn.commit()
except Exception:
traceback.print_exc(file=sys.stdout)
except Exception:
traceback.print_exc(file=sys.stdout)
except Exception:
traceback.print_exc(file=sys.stdout)

async def update_balance_cosmos_all(bot, coin_name: str, forced_coin: str=None):
coin_family = "COSMOS"
timeout = 30
Expand All @@ -6876,6 +7058,9 @@ async def update_balance_cosmos_all(bot, coin_name: str, forced_coin: str=None):
try:
url = getattr(getattr(bot.coin_list, coin_name), "http_address")
main_address = getattr(getattr(bot.coin_list, coin_name), "MainAddress")
is_cosmwasm_token = getattr(getattr(bot.coin_list, coin_name), "is_cosmwasm_token")
contract = getattr(getattr(bot.coin_list, coin_name), "contract")

get_transactions = await get_cosmos_transactions(
self.bot.config['discord']['default_browser_agent'], url, main_address
)
Expand All @@ -6901,6 +7086,8 @@ async def update_balance_cosmos_all(bot, coin_name: str, forced_coin: str=None):
get_user_memo = None
if len(each_tx['tx']['body']['messages']) > 0:
for each_from_to in each_tx['tx']['body']['messages']:
if 'from_address' not in each_from_to:
continue
from_addr = each_from_to['from_address']
to_addr = each_from_to['to_address']
if len(each_from_to['amount']) > 0:
Expand Down Expand Up @@ -6965,7 +7152,12 @@ async def update_balance_cosmos_all(bot, coin_name: str, forced_coin: str=None):
forced_coin = None
if coin_name in ["LUNC", "LUNA"]:
forced_coin = coin_name
tasks.append(update_balance_cosmos_all(self.bot, coin_name, forced_coin=forced_coin))
is_cosmwasm_token = getattr(getattr(self.bot.coin_list, coin_name), "is_cosmwasm_token")
if is_cosmwasm_token == 0:
tasks.append(update_balance_cosmos_all(self.bot, coin_name, forced_coin=forced_coin))
elif is_cosmwasm_token == 1:
main_token = getattr(getattr(self.bot.coin_list, coin_name), "sub_type")
tasks.append(update_balance_cosmos_token(self.bot, main_token, coin_name))

completed = 0
if len(tasks) > 0:
Expand Down Expand Up @@ -12492,7 +12684,7 @@ async def async_withdraw(self, ctx, amount: str, token: str, address: str, extra
fee += int(1.0*factor/10 * 10 ** coin_decimal)
if fee/(10**coin_decimal) > NetFee:
fee = int(NetFee * 10 ** coin_decimal)
NetFee = fee/(10 ** coin_decimal) * 2.0
NetFee = fee/(10 ** coin_decimal) * 4.0
# re-check NetFee
if amount + NetFee > actual_balance:
msg = f"{EMOJI_RED_NO} {ctx.author.mention}, insufficient balance to send out "\
Expand Down Expand Up @@ -12555,13 +12747,45 @@ async def async_withdraw(self, ctx, amount: str, token: str, address: str, extra
if coin_name in ["LUNC"]:
gas = int(2.0*gas)
fee = int(2.0*fee)
send_tx = await self.wallet_api.cosmos_send_tx(
rpchost, chain_id, coin_name, int(get_wallet_seq['account']['account_number']),
int(get_wallet_seq['account']['sequence']), key,
amount, coin_decimal, str(ctx.author.id), address, SERVER_BOT,
NetFee, fee=fee,gas=gas, memo="", timeout=60, hrp=hrp, denom=denom
)
if send_tx:
elif coin_name in ["OSMO"]:
gas = int(3.0*gas)
fee = int(1.5*fee)
is_cosmwasm_token = getattr(getattr(self.bot.coin_list, coin_name), "is_cosmwasm_token")
if is_cosmwasm_token == 0:
send_tx = await self.wallet_api.cosmos_send_tx(
rpchost, chain_id, coin_name, int(get_wallet_seq['account']['account_number']),
int(get_wallet_seq['account']['sequence']), key,
amount, coin_decimal, str(ctx.author.id), address, SERVER_BOT,
NetFee, fee=fee,gas=gas, memo="", timeout=60, hrp=hrp, denom=denom
)
elif is_cosmwasm_token == 1:
key = decrypt_string(getattr(getattr(self.bot.coin_list, coin_name), "walletkey"))
proxy = "http://{}:{}/transfer".format(self.bot.config['api_helper']['connect_ip'], self.bot.config['api_helper']['port_api_sei_send'])
send_tx = await self.wallet_api.cosmos_send_token_wasm(
proxy, rpchost, coin_name, denom, key,
amount, coin_decimal, str(ctx.author.id), address, SERVER_BOT,
NetFee, memo="", timeout=60
)

if send_tx and is_cosmwasm_token == 1:
tx_hash = send_tx['transactionHash']
explorer_link = self.utils.get_explorer_link(coin_name, tx_hash)
fee_txt = "\nWithdrew fee/node: __{} {}__.".format(
num_format_coin(NetFee), coin_name
)
msg = f"{EMOJI_ARROW_RIGHTHOOK} {ctx.author.mention}, you withdrew "\
f"{num_format_coin(amount)} "\
f"{token_display}{equivalent_usd} to _{address}_.\nTransaction hash: _{tx_hash}_{fee_txt}{explorer_link}"
if extra_option is not None:
msg += "\nWith memo: __{}__".format(extra_option)
await ctx.edit_original_message(content=msg, view=None)
await log_to_channel(
"withdraw",
f"User {ctx.author.name}#{ctx.author.discriminator} / {ctx.author.mention} "\
f"successfully withdrew {num_format_coin(amount)} "\
f"{token_display}{equivalent_usd}.{explorer_link}"
)
elif send_tx and is_cosmwasm_token == 0:
# code 13
if send_tx['result']['code'] != 0 and "insufficient fees" in send_tx['result']['log']:
await log_to_channel(
Expand Down

0 comments on commit e2ca6c8

Please sign in to comment.