예제 #1
0
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, tx_fee = find_gas_coin(balances, get_fee=True, payload=payload)
    gas_coin_balance = float(to_bip(balances.get(gas_coin, 0)))

    if not gas_coin or not tx_fee or gas_coin_balance < tx_fee:
        return 'Not enough balance to pay commission'
    tx_fee = float(tx_fee)

    # если в обычной пересылке пришлют сумму без учета комиссии - не будем мучать ошибками
    amount = main_balance - 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)
    NodeAPI.send_tx(tx, wait=wait)
    return True
예제 #2
0
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
예제 #3
0
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
예제 #4
0
    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}