Ejemplo n.º 1
0
def send_asset(text):
    # send 10 EURT antb123*papayame.com or send 1 XLM PUBKEY memo text
    if CONF['private_key'] == '':
        print(
            'no private key setup  - pls type set to set key or c to create wallet'
        )
        return
    val = text.split()
    memo_type = 'text'
    if len(val) < 3:
        print(
            'invalid syntax please use send amount asset receiver e.g.  s 10 EURT antb123*papayame.com'
        )
        return
    amount, asset, address = val[1], val[2].upper(), val[3]
    if '*' in address:
        res = fed(address.split('*')[1], address)
        sendto = res['account_id']
        memo = res['memo']
        memo_type = res['memo_type']
    else:
        sendto = address
        memo = ''
    # override memo, type if given
    if len(val) == 6:
        memo = val[4]
        memo_type = val[5]
    if len(val) == 5:
        memo = val[4]
        memo_type = 'text'
    print_formatted_text(
        HTML("""Are you sure you want to send
                                <ansiyellow>%s</ansiyellow>
                                <ansired>%s %s</ansired>
                                with memo of <ansiblue>%s</ansiblue> (y/n)
                                """ % (sendto, asset, amount, memo)))
    text = session.prompt(u'> ', default='y')
    if text != 'y': return
    ret, asset_issuer = get_balance_issuer(amount, asset)
    if ret: return
    retsan = send_sanity(sendto, memo_type, asset)
    if not retsan: return
    send = Builder(CONF['private_key'], network=CONF['network'])
    if asset != 'XLM':
        send.append_payment_op(sendto, amount, asset, asset_issuer)
    else:
        send.append_payment_op(sendto, amount)
    if memo != '' and memo_type == 'text':
        send.add_text_memo(memo)
    if memo != '' and memo_type == 'id':
        send.add_id_memo(memo)
    if CONF['multisig'] != '':
        print(
            'You have 2of2 multisig - send this data to the other key to sign when you get it back type signsend data'
        )
        print(send.gen_xdr())
        return
    send.sign()
    send.submit()
Ejemplo n.º 2
0
    def test_add_memo(self, test_data):
        builder = Builder(test_data.cold_secret, sequence=1, fee=100)

        builder.add_text_memo("hello")
        assert builder.memo == memo.TextMemo("hello")

        builder.add_id_memo(123123)
        assert builder.memo == memo.IdMemo(123123)

        hash = b"\x95\xe5\xbb\x95\x15\xd9\x9f\x82\x9d\xf9\x93\xc3'\x8e\xeb\xf1\nj!\xda\xa4\xa1\xe4\xf2<6cG}\x17\x97\xfe"
        builder.add_hash_memo(hash)
        assert builder.memo == memo.HashMemo(hash)
        builder.add_ret_hash_memo(hash)
        assert builder.memo == memo.RetHashMemo(hash)
Ejemplo n.º 3
0
class Interface:
    """
    Interface to handle all API calls to third-party account.
    """
    def __init__(self, account):
        self.account = account
        if account.secret:
            self.builder = Builder(secret=account.secret,
                                   network=account.network)
        self.address = Address(address=account.account_id,
                               network=account.network)

    def _get_new_receives(self):
        # Get all stored transactions for account
        transactions = ReceiveTransaction.filter(admin_account=self.account)

        # Set the cursor according to latest stored transaction:
        if not transactions:
            cursor = None
        else:
            cursor = int(transactions.latest().data['paging_token']) + 1

        # Get new transactions from the stellar network:
        new_transactions = self._get_receives(cursor=cursor)

        return new_transactions

    def _get_receives(self, cursor=None):
        # If cursor was specified, get all transactions after the cursor:
        if cursor:
            transactions = self.address.payments(cursor=cursor)['_embedded']['records']
            print(transactions)
            for i, tx in enumerate(transactions):
                if tx.get('to') != self.account.account_id:
                    transactions.pop(i)  # remove sends

        # else just get all the transactions:
        else:
            transactions = self.address.payments()['_embedded']['records']
            for i, tx in enumerate(transactions):
                if tx.get('from') == self.account.account_id:
                    transactions.pop(i)  # remove sends

        return transactions

    def _process_receive(self, tx):
        # Get memo:
        details = requests.get(url=tx['_links']['transaction']['href']).json()
        memo = details.get('memo')
        print('memo: ' + str(memo))
        if memo:
            account_id = memo + '*rehive.com'
            user_account = UserAccount.objects.get(account_id=account_id)
            user_email = user_account.user_id  # for this implementation, user_id is the user's email
            amount = to_cents(Decimal(tx['amount']), 7)

            if tx['asset_type'] == 'native':
                currency = 'XLM'
                issuer = ''
            else:
                currency = tx['asset_code']
                issuer_address = tx['asset_issuer']
                issuer = Asset.objects.get(account_id=issuer_address, code=currency).issuer

            # Create Transaction:
            tx = ReceiveTransaction.objects.create(user_account=user_account,
                                                   external_id=tx['hash'],
                                                   recipient=user_email,
                                                   amount=amount,
                                                   currency=currency,
                                                   issuer=issuer,
                                                   status='Waiting',
                                                   data=tx,
                                                   metadata={'type': 'stellar'}
                                                   )

            # TODO: Move tx.upload_to_rehive() to a signal to auto-run after Transaction creation.
            tx.upload_to_rehive()

            return True

    @staticmethod
    def _is_valid_address(address: str) -> bool:
        # TODO: Replace with real address check.
        if len(address) == 56 and '*' not in address:
            return True
        else:
            return False

    # This function should always be included if transactions are received to admin account and not added via webhooks:
    def process_receives(self):
        # Get new receive transactions
        new_transactions = self._get_new_receives()

        # Add each transaction to Rehive and log in transaction table:
        for tx in new_transactions:
            self._process_receive(tx)

    # This function should always be included.
    def process_send(self, tx):
        if self._is_valid_address(tx.recipient):
            address = tx.recipient
        else:
            federation = get_federation_details(tx.recipient)
            if federation['memo_type'] == 'text':
                self.builder.add_text_memo(federation['memo'])
            elif federation['memo_type'] == 'id':
                self.builder.add_id_memo(federation['memo'])
            elif federation['memo_type'] == 'hash':
                self.builder.add_hash_memo(federation['memo'])
            else:
                raise NotImplementedAPIError('Invalid memo type specified.')

            address = federation['account_id']

        # Create account or create payment:
        if tx.currency == 'XLM':
            try:
                address_obj = self.address
                address_obj.get()
                self.builder.append_payment_op(address, tx.amount, 'XLM')
            except APIException as exc:
                if exc.status_code == 404:
                    self.builder.append_create_account_op(address, tx.amount)
        else:
            # Get issuer address details:
            issuer_address = get_issuer_address(tx.issuer, tx.currency)

            address_obj = self.address
            address_obj.get()
            self.builder.append_payment_op(address, tx.amount, tx.currency, issuer_address)

        try:
            self.builder.sign()
            self.builder.submit()
        except Exception as exc:
            print(exc.payload)

    def get_balance(self):
        address = self.address
        address.get()
        for balance in address.balances:
            if balance['asset_type'] == 'native':
                return to_cents(Decimal(balance['balance']), 7)

    def get_issuer_address(self, issuer, asset_code):
        if self._is_valid_address(issuer):
            address = issuer
        else:
            if '*' in issuer:
                address = get_federation_details(issuer)['account_id']
            else:  # assume it is an anchor domain
                address = address_from_domain(issuer, asset_code)

        return address

    def trust_issuer(self, asset_code, issuer):
        logger.info('Trusting issuer: %s %s' % (issuer, asset_code))
        address = self.get_issuer_address(issuer, asset_code)
        self.builder.append_trust_op(address, asset_code)

        try:
            self.builder.sign()
            self.builder.submit()
        except Exception as exc:
            print(exc.payload)

    # Generate new crypto address/ account id
    @staticmethod
    def new_account_id(**kwargs):
        metadata = kwargs.get('metadata')
        account_id = metadata['username'] + '*' + getattr(settings, 'STELLAR_WALLET_DOMAIN')
        return account_id

    def get_account_details(self):
        address = self.account.account_id
        qr_code = create_qr_code_url('stellar:' + str(address))
        return {'account_id': address, 'metadata': {'qr_code': qr_code}}