def load_bytes_data(addr: PublicKey, conn: Client): res = conn.get_account_info(addr) if ("result" not in res) or ("value" not in res["result"]) or ( "data" not in res["result"]["value"]): raise Exception("Cannot load byte data.") data = res["result"]["value"]["data"][0] return base64.decodebytes(data.encode("ascii"))
def load_binary_option(self, api_endpoint, pool_account): client = Client(api_endpoint) try: pool_data = base64.b64decode( client.get_account_info(pool_account)['result']['value'] ['data'][0]) except Exception as e: return json.dumps({ 'status': HTTPStatus.BAD_REQUEST, 'msg': str(e), }) pubkey = 'B' * 32 raw_bytes = struct.unpack( f"<BQ?{pubkey}{pubkey}{pubkey}{pubkey}{pubkey}{pubkey}", pool_data) i = 0 pool = {} pool["decimals"] = raw_bytes[i] i += 1 pool["circulation"] = raw_bytes[i] i += 1 pool["settled"] = raw_bytes[i] i += 1 pool["escrow_mint"] = base58.b58encode(bytes( raw_bytes[i:i + 32])).decode('ascii') i += 32 pool["escrow"] = base58.b58encode(bytes(raw_bytes[i:i + 32])).decode('ascii') i += 32 pool["long_mint"] = base58.b58encode(bytes( raw_bytes[i:i + 32])).decode('ascii') i += 32 pool["short_mint"] = base58.b58encode(bytes( raw_bytes[i:i + 32])).decode('ascii') i += 32 pool["owner"] = base58.b58encode(bytes(raw_bytes[i:i + 32])).decode('ascii') i += 32 pool["winning_side"] = base58.b58encode(bytes( raw_bytes[i:i + 32])).decode('ascii') i += 32 return pool
def collect(self, api_endpoint, pool_account, collector, skip_confirmation=True): msg = "" client = Client(api_endpoint) msg += "Initialized client" signers = [Account(self.private_key)] pool = self.load_binary_option(api_endpoint, pool_account) pool_account = PublicKey(pool_account) collector_account = PublicKey(collector) escrow_account = PublicKey(pool["escrow"]) escrow_mint_account = PublicKey(pool["escrow_mint"]) long_token_mint_account = PublicKey(pool["long_mint"]) short_token_mint_account = PublicKey(pool["short_mint"]) token_account = PublicKey(TOKEN_PROGRAM_ID) escrow_authority_account = PublicKey.find_program_address( [ bytes(long_token_mint_account), bytes(short_token_mint_account), bytes(token_account), bytes(PublicKey(BINARY_OPTION_PROGRAM_ID)) ], PublicKey(BINARY_OPTION_PROGRAM_ID), )[0] # Transaction tx = Transaction() atas = [] for mint_account in (long_token_mint_account, short_token_mint_account, escrow_mint_account): token_pda_address = get_associated_token_address( collector_account, mint_account) associated_token_account_info = client.get_account_info( token_pda_address) account_info = associated_token_account_info['result']['value'] if account_info is not None: account_state = ACCOUNT_LAYOUT.parse( base64.b64decode(account_info['data'][0])).state else: account_state = 0 if account_state == 0: msg += f" | Error Fetching PDA: {token_pda_address}" raise Exception() else: msg += f" | Fetched PDA: {token_pda_address}" atas.append(token_pda_address) collect_ix = collect_instruction( pool_account, collector_account, atas[0], atas[1], atas[2], long_token_mint_account, short_token_mint_account, escrow_account, escrow_authority_account, token_account, ) tx = tx.add(collect_ix) try: response = client.send_transaction( tx, *signers, opts=types.TxOpts(skip_confirmation=skip_confirmation)) return json.dumps({ 'status': HTTPStatus.OK, 'msg': msg + f" | Collect successful", 'tx': response.get('result') if skip_confirmation else response['result']['transaction']['signatures'], }) except Exception as e: msg += f" | ERROR: Encountered exception while attempting to send transaction: {e}" print(msg) raise (e)
def trade(self, api_endpoint, pool_account, buyer_encrypted_private_key, seller_encrypted_private_key, size, buyer_price, seller_price, skip_confirmation=True): msg = "" client = Client(api_endpoint) msg += "Initialized client" # Create account objects buyer_private_key = list( self.cipher.decrypt(buyer_encrypted_private_key)) seller_private_key = list( self.cipher.decrypt(seller_encrypted_private_key)) assert (len(buyer_private_key) == 32) assert (len(seller_private_key) == 32) source_account = Account(self.private_key) buyer = Account(buyer_private_key) seller = Account(seller_private_key) # Signers signers = [buyer, seller, source_account] pool = self.load_binary_option(api_endpoint, pool_account) # List non-derived accounts pool_account = PublicKey(pool_account) escrow_account = PublicKey(pool["escrow"]) escrow_mint_account = PublicKey(pool["escrow_mint"]) long_token_mint_account = PublicKey(pool["long_mint"]) short_token_mint_account = PublicKey(pool["short_mint"]) buyer_account = buyer.public_key() seller_account = seller.public_key() token_account = PublicKey(TOKEN_PROGRAM_ID) escrow_owner_account = PublicKey.find_program_address( [ bytes(long_token_mint_account), bytes(short_token_mint_account), bytes(token_account), bytes(PublicKey(BINARY_OPTION_PROGRAM_ID)) ], PublicKey(BINARY_OPTION_PROGRAM_ID), )[0] # Transaction tx = Transaction() atas = [] for acct in [buyer_account, seller_account]: acct_atas = [] for mint_account in (long_token_mint_account, short_token_mint_account, escrow_mint_account): token_pda_address = get_associated_token_address( acct, mint_account) associated_token_account_info = client.get_account_info( token_pda_address) account_info = associated_token_account_info['result']['value'] if account_info is not None: account_state = ACCOUNT_LAYOUT.parse( base64.b64decode(account_info['data'][0])).state else: account_state = 0 if account_state == 0: msg += f" | Creating PDA: {token_pda_address}" associated_token_account_ix = create_associated_token_account( payer=source_account.public_key(), owner=acct, mint=mint_account, ) tx = tx.add(associated_token_account_ix) else: msg += f" | Fetched PDA: {token_pda_address}" acct_atas.append(token_pda_address) atas.append(acct_atas) trade_ix = trade_instruction( pool_account, escrow_account, long_token_mint_account, short_token_mint_account, buyer_account, seller_account, atas[0][2], atas[1][2], atas[0][0], atas[0][1], atas[1][0], atas[1][1], escrow_owner_account, token_account, int(size), int(buyer_price), int(seller_price), ) tx = tx.add(trade_ix) # Send request try: response = client.send_transaction( tx, *signers, opts=types.TxOpts(skip_confirmation=skip_confirmation)) return json.dumps({ 'status': HTTPStatus.OK, 'msg': msg + f" | Trade successful", 'tx': response.get('result') if skip_confirmation else response['result']['transaction']['signatures'], }) except Exception as e: msg += f" | ERROR: Encountered exception while attempting to send transaction: {e}" raise (e)