def send_coins(wallet: PushWallet, to=None, amount=None, payload='', wait=True, gas_coin=None): private_key = MinterWallet.create(mnemonic=wallet.mnemonic)['private_key'] response = NodeAPI.get_balance(wallet.address) nonce = int(response['transaction_count']) + 1 balances = response['balance'] balances_bip = effective_balance(balances) main_coin, main_balance_bip = max(balances_bip.items(), key=lambda i: i[1]) main_balance = float(to_bip(balances[main_coin])) gas_coin_balance = main_balance if gas_coin: gas_coin_balance = float(to_bip(balances.get(gas_coin, 0))) tx = send_coin_tx(private_key, main_coin, amount, to, nonce, payload=payload, gas_coin=gas_coin or main_coin) tx_fee = float(to_bip(NodeAPI.estimate_tx_commission(tx.signed_tx)['commission'])) if gas_coin_balance < tx_fee: return 'Not enough balance to pay commission' # если в обычной пересылке пришлют сумму без учета комиссии - не будем мучать ошибками amount = amount - tx_fee if amount == truncate(main_balance, 4) \ and gas_coin == main_coin and not payload else amount tx_fee = tx_fee if gas_coin == main_coin else 0 if amount > main_balance - tx_fee: return 'Not enough balance' tx = send_coin_tx(private_key, main_coin, amount, to, nonce, payload=payload, gas_coin=gas_coin or main_coin) NodeAPI.send_tx(tx, wait=wait) return True
def mobile_top_up(wallet: PushWallet, phone=None, amount=None): phone_reqs = get_tx_requirements(phone) if not phone_reqs: return False response = API.get_balance(wallet.address) balance = response['balance'] nonce = int(response['transaction_count']) + 1 bip_values = calc_bip_values(balance) total_bip = sum(bip_values.values()) to_send = amount or total_bip private_key = MinterWallet.create(mnemonic=wallet.mnemonic)['private_key'] tx = send_coin_tx(private_key, 'BIP', to_send, BIP2PHONE_PAYMENT_ADDRESS, nonce, payload=phone_reqs['payload']) fee = to_bip(tx.get_fee()) if to_send < phone_reqs['min_bip_value'] + fee: return False tx = send_coin_tx(private_key, 'BIP', to_send - fee, BIP2PHONE_PAYMENT_ADDRESS, nonce, payload=phone_reqs['payload']) API.send_tx(tx, wait=True) return True
def mobile_top_up(wallet: PushWallet, phone=None, amount=None, confirm=True): if not confirm: return get_info() amount = float(amount) phone_reqs = get_tx_requirements(phone) if not phone_reqs: return f'Phone number {phone} not supported or invalid' response = MscanAPI.get_balance(wallet.address) balance = response['balance'] available_bip = float(to_bip(balance['BIP'])) nonce = int(response['transaction_count']) + 1 to_send = amount or available_bip private_key = MinterWallet.create(mnemonic=wallet.mnemonic)['private_key'] tx = send_coin_tx(private_key, 'BIP', to_send, BIP2PHONE_PAYMENT_ADDRESS, nonce, payload=phone_reqs['payload']) fee = to_bip(tx.get_fee()) min_topup = phone_reqs['min_bip_value'] + fee effective_topup = Decimal(to_send) - fee if available_bip < to_send: return 'Not enough balance' if effective_topup < min_topup: return f"Minimal top-up: {min_topup} BIP" tx = send_coin_tx(private_key, 'BIP', effective_topup, BIP2PHONE_PAYMENT_ADDRESS, nonce, payload=phone_reqs['payload']) MscanAPI.send_tx(tx, wait=True) return True
def send_coins(wallet: PushWallet, to=None, amount=None): private_key = MinterWallet.create(mnemonic=wallet.mnemonic)['private_key'] response = API.get_balance(wallet.address) nonce = int(response['transaction_count']) + 1 balance_bip = float(to_bip(response['balance']['BIP'])) # если вдруг пришлют сумму без учета комиссии - не будем мучать ошибками) amount = amount - 0.01 if amount == balance_bip else amount if amount > balance_bip - 0.01: return False tx = send_coin_tx(private_key, 'BIP', amount, to, nonce) API.send_tx(tx, wait=True) return True
def mobile_top_up(wallet: PushWallet, phone=None, amount=None, confirm=True): if not confirm: return get_info() phone_reqs = get_tx_requirements(phone) if not phone_reqs: return f'Phone number {phone} not supported or invalid' response = NodeAPI.get_balance(wallet.address) balance = response['balance'] balances_bip = effective_balance(balance) main_coin, main_balance_bip = max(balances_bip.items(), key=lambda i: i[1]) balance_coin = to_bip(balance[main_coin]) nonce = int(response['transaction_count']) + 1 to_send = amount or balance_coin private_key = MinterWallet.create(mnemonic=wallet.mnemonic)['private_key'] gas_coin = find_gas_coin(balance) if not gas_coin: return 'Coin not spendable. Send any coin to pay fee' # fee = estimate_custom_fee(gas_coin) min_topup = phone_reqs['min_bip_value'] effective_topup = rub_to_bip( to_send) if main_coin == 'ROUBLE' else main_balance_bip if balance_coin < to_send: return 'Not enough balance' if effective_topup < min_topup: return f"Minimal top-up: {min_topup} BIP" tx = send_coin_tx(private_key, main_coin, to_send, BIP2PHONE_PAYMENT_ADDRESS, nonce, payload=phone_reqs['payload'], gas_coin=gas_coin) try: NodeAPI.send_tx(tx, wait=True) except MinterAPIException as exc: return exc.message return True
def generate_push(campaign): response = NodeAPI.get_balance(campaign.address) balances = response['balance'] campaign_balance = to_bip(balances.get(campaign.coin, '0')) if not campaign_balance: logging.info( f'Campaign {campaign.link_id} {campaign.name}: balance too low {campaign_balance}' ) return tx_fee = estimate_custom_fee(campaign.coin) reward = to_bip(campaign.action_reward) if campaign_balance < reward + tx_fee: logging.info( f'Campaign {campaign.link_id} {campaign.name}: balance too low {campaign_balance}' ) return push = generate_and_save_wallet() private_key = MinterWallet.create( mnemonic=campaign.mnemonic)['private_key'] nonce = int(response['transaction_count']) + 1 tx = send_coin_tx(private_key, campaign.coin, reward + tx_fee, push.address, nonce, gas_coin=campaign.coin) NodeAPI.send_tx(tx, wait=True) logging.info( f'Campaign {campaign.link_id} {campaign.name} rewarded {reward} {campaign.coin}, fee {tx_fee}' ) campaign.times_completed += 1 if campaign.times_completed == campaign.count: campaign.status = 'close' logging.info(f'Campaign {campaign.link_id} {campaign.name} finished!') campaign.save() return YYY_PUSH_URL + push.link_id
def push_create(): """ swagger: swagger/core/push-create.yml """ payload = request.get_json() or {} sender, recipient = payload.get('sender'), payload.get('recipient') password = payload.get('password') amount = payload.get('amount') coin = payload.get('coin', 'BIP') customization_setting_id = payload.get('customization_setting_id') setting = CustomizationSetting.get_or_none(id=customization_setting_id) if not setting: jsonify({'error': 'Customization setting does not exist' }), HTTPStatus.BAD_REQUEST wallet = generate_and_save_wallet( sender=sender, recipient=recipient, password=password, customization_setting_id=customization_setting_id) response = {'address': wallet.address, 'link_id': wallet.link_id} if amount: w = MinterWallet.create() tx = send_coin_tx(w['private_key'], coin, float(amount), w['address'], 1, gas_coin=coin) tx_fee = float( to_bip(NodeAPI.estimate_tx_comission(tx.signed_tx)['commission'])) response['deeplink'] = TxDeeplink.create('send', to=wallet.address, value=float(amount) + tx_fee, coin=coin).mobile return jsonify(response)
def delete(self, campaign_id): campaign = RewardCampaign.get_or_none(link_id=campaign_id, status='open') if not campaign: return {}, HTTPStatus.NOT_FOUND response = NodeAPI.get_balance(campaign.address) balances = response['balance'] campaign_balance = to_bip(balances.get(campaign.coin, '0')) if campaign_balance: tx_fee = estimate_custom_fee(campaign.coin) gas_coin = find_gas_coin( balances) if tx_fee is None else campaign.coin if not gas_coin: return { 'error': f'Campaign coin not spendable.' f'Send any coin to campaign address {campaign.address} to pay fee' }, HTTPStatus.BAD_REQUEST private_key = MinterWallet.create( mnemonic=campaign.mnemonic)['private_key'] refund_address = get_first_transaction(campaign.address) nonce = int(response['transaction_count']) + 1 tx_fee = 0 if tx_fee is None else tx_fee tx = send_coin_tx(private_key, campaign.coin, campaign_balance - tx_fee, refund_address, nonce, gas_coin=campaign.coin) NodeAPI.send_tx(tx, wait=True) campaign.status = 'closed' campaign.save() return {'success': True}