示例#1
0
def effective_value(value, coin):
    tx_fee = estimate_custom_fee(coin)
    if tx_fee is None:
        return value
    if tx_fee >= value:
        return Decimal(0)
    return Decimal(value) - tx_fee
示例#2
0
def find_gas_coin(balances):
    for coin, balance_pip in balances.items():
        tx_fee = estimate_custom_fee(coin)
        if not tx_fee:
            continue
        if to_bip(balance_pip) - tx_fee >= 0:
            return coin
示例#3
0
def deeplink():
    address = request.args.get('address')
    amount = request.args.get('amount')
    coin = request.args.get('coin')
    nofee = 'nofee' in request.args

    if not address:
        return jsonify({
            'success': False,
            'error': '"address" key is required'
        }), HTTPStatus.BAD_REQUEST
    if not amount:
        return jsonify({
            'success': False,
            'error': '"amount" key is required'
        }), HTTPStatus.BAD_REQUEST
    if not coin:
        return jsonify({
            'success': False,
            'error': '"coin" key is required'
        }), HTTPStatus.BAD_REQUEST

    address = address.strip()
    fee = 0
    if not nofee:
        fee = float(estimate_custom_fee(coin) or 0)
    amount = float(amount) + fee
    coin = coin.strip().upper()
    link = TxDeeplink.create('send',
                             to=address,
                             value=amount,
                             coin=coin,
                             data_only=False)
    return {'success': True, 'web': link.web, 'mobile': link.mobile}
示例#4
0
def find_gas_coin(balances, get_fee=False, payload=''):
    for coin, balance_pip in balances.items():
        tx_fee = estimate_custom_fee(coin, payload=payload)
        if not tx_fee:
            continue
        if to_bip(balance_pip) - tx_fee >= 0:
            return coin if not get_fee else (coin, tx_fee)
    return None if not get_fee else (None, None)
示例#5
0
    def post(self):
        args = parser_campaign_create.parse_args()
        count = args['count']
        coin = args['action_coin']
        name = args['name']
        action_type = args['action_type']
        action_reward = args['action_reward']
        action_link = args['action_link']
        action_duration = args['action_duration']

        action = {
            'type': action_type,
            'reward': action_reward,
            'link': action_link,
            'duration': action_duration
        }
        campaign_id = uuid()
        wallet = MinterWallet.create()
        action_reward = float(action['reward'])
        one_tx_fee = float(estimate_custom_fee(coin) or 0)
        campaign_cost = (action_reward + one_tx_fee) * count
        deeplink = TxDeeplink.create('send',
                                     to=wallet['address'],
                                     value=campaign_cost,
                                     coin=coin)

        icon_storage = args['icon']
        filename = images.save(
            icon_storage,
            name=f'{campaign_id}.{extension(icon_storage.filename)}')
        icon = RewardIcon.create(filename=filename, url=images.url(filename))
        RewardCampaign.create(link_id=campaign_id,
                              address=wallet['address'],
                              mnemonic=wallet['mnemonic'],
                              name=name,
                              count=count,
                              coin=coin,
                              action_type=action['type'],
                              action_reward=to_pip(action_reward),
                              action_params=action,
                              icon=icon)
        return {
            'id': campaign_id,
            'address': wallet['address'],
            'deeplink': deeplink.web
        }
示例#6
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
示例#7
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}