コード例 #1
0
    async def get_parent_vasp_account(
        self, vasp_account_address: typing.Union[diem_types.AccountAddress,
                                                 str]
    ) -> rpc.Account:
        """get parent_vasp account

        accepts child/parent vasp account address, returns parent vasp account

        raise ValueError if given account address is not ChildVASP or ParentVASP account
        address
        raise AccountNotFoundError if no account found by given account address, or
        could not find the account by the parent_vasp_address found in ChildVASP account.
        """

        account = await self.must_get_account(vasp_account_address)

        if account.role.type == ACCOUNT_ROLE_PARENT_VASP:
            return account
        if account.role.type == ACCOUNT_ROLE_CHILD_VASP:
            return await self.get_parent_vasp_account(
                account.role.parent_vasp_address)

        hex = utils.account_address_hex(vasp_account_address)
        raise ValueError(
            f"given account address({hex}) is not a VASP account: {account}")
コード例 #2
0
def send_fake_tx(amount=100, send_to_self=False) -> Tuple[int, Transaction]:
    user = OneUser.run(db_session,
                       account_amount=100_000_000_000,
                       account_currency=DiemCurrency.XUS)
    account_id = user.account_id
    amount = amount
    payment_type = types.TransactionType.EXTERNAL
    currency = diem_utils.types.currencies.DiemCurrency.XUS
    destination_address = "receiver_address"
    destination_subaddress = "receiver_subaddress"

    if send_to_self:
        destination_address = account_address_hex(
            context.get().config.vasp_address)
        destination_subaddress = generate_new_subaddress(account_id)

    send_tx = send_transaction(
        sender_id=account_id,
        amount=amount,
        currency=currency,
        payment_type=payment_type,
        destination_address=destination_address,
        destination_subaddress=destination_subaddress,
    )

    return account_id, get_transaction(send_tx.id) if send_tx else None
コード例 #3
0
 def get_account_state_with_proof(
     self,
     account_address: diem_types.AccountAddress,
     version: typing.Optional[int] = None,
     ledger_version: typing.Optional[int] = None,
 ) -> rpc.AccountStateWithProof:
     address = utils.account_address_hex(account_address)
     params = [address, version, ledger_version]
     return self.execute("get_account_state_with_proof", params,
                         _parse_obj(lambda: rpc.AccountStateWithProof()))
コード例 #4
0
    async def must_get_account(
        self, account_address: typing.Union[diem_types.AccountAddress, str]
    ) -> rpc.Account:
        """must_get_account raises AccountNotFoundError if account could not be found by given address"""

        account = await self.get_account(account_address)
        if account is None:
            hex = utils.account_address_hex(account_address)
            raise AccountNotFoundError(f"account not found by address: {hex}")
        return account
コード例 #5
0
def test_sync():
    jsonrpc_client = testnet.create_client()
    faucet = testnet.Faucet(jsonrpc_client)

    parent_vasp = faucet.gen_account()
    account = jsonrpc_client.get_account(parent_vasp.account_address)

    processor = ProcessorStub()

    config = DEFL_CONFIG.copy()
    config["accounts"] = [account.address]
    config["processor"] = processor

    with tempfile.TemporaryDirectory() as tmpdir:
        config["progress_file_path"] = tmpdir + "/progress"

        client = LRWPubSubClient(config)
        state = client.init_progress_state()

        assert state == {account.received_events_key: 0}
        new_state = client.sync(state)

        assert state == {
            account.received_events_key: 0
        }, "state pass in should be not be changed"

        # new state seq num increased, as we found the event transfered from DD account when
        # we genreate the account.
        assert new_state == {account.received_events_key: 1}
        # new state is saved
        assert new_state == client.progress.fetch_state()
        assert len(processor.events) == 1
        assert processor.events[0].sender == utils.account_address_hex(
            testnet.DESIGNATED_DEALER_ADDRESS)
        assert processor.events[0].receiver == account.address

        # nothing happened, do sync once, new state should be same
        new_state2 = client.sync(new_state)
        assert new_state2 == new_state
        assert new_state2 == client.progress.fetch_state()
        assert len(processor.events) == 1

        # transfer coins to account, one new event should be fetched
        currency = account.balances[0].currency
        faucet.mint(parent_vasp.auth_key.hex(), 1_000, currency)
        sleep(2)

        new_state3 = client.sync(new_state2)
        assert new_state3 == {account.received_events_key: 2}
        assert new_state3 == client.progress.fetch_state()
        assert len(processor.events) == 2

        # when init progress state, we should get back state last synced
        reload_state = client.init_progress_state()
        assert reload_state == new_state3
コード例 #6
0
    def __init__(
        self,
        diem_client: DiemClient,
        custody_account_name: Optional[str] = _DEFAULT_ACCOUNT_NAME,
    ):
        self._diem_client = diem_client
        self._custody: Custody = Custody()
        self._custody_account_name = custody_account_name

        self.account = self._custody.get_account(custody_account_name)
        self.address_str = utils.account_address_hex(self.account.account_address)
コード例 #7
0
async def test_get_parent_vasp_account(client: AsyncClient):
    faucet = Faucet(client)

    parent_vasp, child_vasp = await faucet.gen_vasp()

    account = await client.get_parent_vasp_account(child_vasp.account_address)

    expected_address = utils.account_address_hex(parent_vasp.account_address)
    assert account.address == expected_address

    account = await client.get_parent_vasp_account(parent_vasp.account_address)
    assert account.address == expected_address
コード例 #8
0
    async def get_account(
        self, account_address: typing.Union[diem_types.AccountAddress, str]
    ) -> typing.Optional[rpc.Account]:
        """get on-chain account information

        Returns None if account not found
        See [JSON-RPC API Doc](https://github.com/diem/diem/blob/master/json-rpc/docs/method_get_account.md)
        """

        address = utils.account_address_hex(account_address)
        return await self.execute("get_account", [address],
                                  _parse_obj(lambda: rpc.Account()))
コード例 #9
0
    def __trade_and_execute_buy(self, quote, trade, diem_deposit_address):
        if not diem_deposit_address:
            raise TradeError("Can't execute trade without a deposit address")

        receiver_vasp, receiver_subaddress = identifier.decode_account(
            diem_deposit_address, identifier.HRPS[CHAIN_ID.to_int()])

        tx_version, tx_sequence = self.send_transaction(
            currency=quote.currency_pair.value.base,
            amount=quote.amount,
            dest_vasp_address=utils.account_address_hex(receiver_vasp),
            dest_sub_address=receiver_subaddress.hex(),
        )
        trade.executed(tx_version)
コード例 #10
0
def init_onchain_account(custody_private_keys, account_name,
                         account: LocalAccount, base_url, compliance_key,
                         chain_id: int):
    account_addr = utils.account_address_hex(account.account_address)
    print(
        f'Creating and initialize blockchain account {account_name} @ {account_addr}'
    )
    os.environ["CUSTODY_PRIVATE_KEYS"] = custody_private_keys
    Custody.init(diem_types.ChainId.from_int(chain_id))
    vasp = Vasp(diem_client, account_name)
    vasp.setup_blockchain(base_url, compliance_key)
    print(f'Account initialization done!')

    return vasp
コード例 #11
0
    async def get_account_sequence(
            self, account_address: typing.Union[diem_types.AccountAddress,
                                                str]) -> int:
        """get on-chain account sequence number

        Calls get_account to find on-chain account information and return it's sequence.
        Raises AccountNotFoundError if get_account returns None
        """

        account = await self.get_account(account_address)
        if account is None:
            hex = utils.account_address_hex(account_address)
            raise AccountNotFoundError(f"account not found by address: {hex}")

        return int(account.sequence_number)
コード例 #12
0
def refund(payment):
    if not payment_can_refund(payment):
        raise InvalidPaymentStatus("unclearedrefund")

    if not len(payment.chain_transactions) == 1:
        raise InvalidPaymentStatus("chain_transactions")
    # TODO - support refund of multiple payments

    # TODO - Resolve refund address, currency and amount from blockchain

    target_transaction = payment.chain_transactions[0]
    if target_transaction.is_refund:
        raise InvalidPaymentStatus("refund_transaction")

    refund_target_address, refund_target_sub_address = identifier.decode_account(
        target_transaction.sender_address, CHAIN_HRP)
    refund_target_address = utils.account_address_hex(refund_target_address)
    refund_target_sub_address = refund_target_sub_address.hex()

    refund_amount = target_transaction.amount  # payment.requested_amount
    refund_currency = DiemCurrency(target_transaction.currency)

    payment.set_status(PaymentStatus.refund_requested)

    refund_tx_id = None

    try:
        wallet = OnchainWallet()

        refund_tx_id, _ = wallet.send_transaction(
            refund_currency,
            refund_amount,
            refund_target_address,
            refund_target_sub_address,  # TODO - new sub_address for refund?
        )
        payment.add_chain_transaction(
            amount=refund_amount,
            sender_address=wallet.address_str,
            currency=refund_currency,
            tx_id=refund_tx_id,
            is_refund=True,
        )
        payment.set_status(PaymentStatus.refund_completed)
    except Exception as e:  # TODO - narrow to blockchain exception
        logger.exception("Failed during refund")
        payment.set_status(PaymentStatus.refund_error)

    return refund_tx_id, target_transaction
コード例 #13
0
    async def get_account_transaction(
        self,
        account_address: typing.Union[diem_types.AccountAddress, str],
        sequence: int,
        include_events: typing.Optional[bool] = None,
    ) -> typing.Optional[rpc.Transaction]:
        """get on-chain account transaction by sequence number

        Returns None if transaction is not found

        See [JSON-RPC API Doc](https://github.com/diem/diem/blob/master/json-rpc/docs/method_get_account_transaction.md)
        """

        address = utils.account_address_hex(account_address)
        params = [address, int(sequence), bool(include_events)]
        return await self.execute("get_account_transaction", params,
                                  _parse_obj(lambda: rpc.Transaction()))
コード例 #14
0
    async def get_account_transactions(
        self,
        account_address: typing.Union[diem_types.AccountAddress, str],
        sequence: int,
        limit: int,
        include_events: typing.Optional[bool] = None,
    ) -> typing.List[rpc.Transaction]:
        """get on-chain account transactions by start sequence number and limit size

        Returns empty list if no transactions found

        See [JSON-RPC API Doc](https://github.com/diem/diem/blob/master/json-rpc/docs/method_get_account_transactions.md)
        """

        address = utils.account_address_hex(account_address)
        params = [address, int(sequence), int(limit), bool(include_events)]
        return await self.execute("get_account_transactions", params,
                                  _parse_list(lambda: rpc.Transaction()))
コード例 #15
0
def test_get_parent_vasp_account():
    client = testnet.create_client()
    faucet = testnet.Faucet(client)

    parent_vasp = faucet.gen_account()
    child_vasp = LocalAccount.generate()
    signed_txn = create_child_vasp_txn(parent_vasp, child_vasp)

    client.submit(signed_txn)
    client.wait_for_transaction(signed_txn)

    account = client.get_parent_vasp_account(child_vasp.account_address)

    expected_address = utils.account_address_hex(parent_vasp.account_address)
    assert account.address == expected_address

    account = client.get_parent_vasp_account(parent_vasp.account_address)
    assert account.address == expected_address
コード例 #16
0
    def mint(
        self,
        authkey_hex: str,
        amount: int,
        identifier: str,
        session: Optional[requests.Session] = None,
        timeout: Optional[Union[float, Tuple[float, float]]] = None,
    ) -> int:
        dd_address_hex = account_address_hex(DESIGNATED_DEALER_ADDRESS)
        account = BlockchainMock.get_account_resource(dd_address_hex)
        sequence = account.sequence_number
        version = BlockchainMock.blockchain.version

        decoded_addr, decoded_subaddr = decode_account(authkey_hex)

        metadata = general_metadata(to_subaddress=decoded_subaddr)

        address_hex_bytes = account_address_bytes(decoded_addr)

        process_incoming_transaction(
            sender_address=dd_address_hex,
            receiver_address=authkey_hex,
            sequence=sequence,
            amount=amount,
            currency=DiemCurrency.Coin1,
            metadata=metadata,
        )

        BlockchainMock.blockchain.version += 1

        tx = MockSignedTransaction(
            sender=bytes.fromhex(ASSOC_AUTHKEY),
            amount=amount,
            currency=identifier,
            receiver=address_hex_bytes,
            metadata=metadata,
            sequence=account.sequence_number,
            version=version,
        )
        account.sequence_number += 1
        account.transactions[sequence] = tx
        BlockchainMock.blockchain.transactions[version] = tx

        return sequence
コード例 #17
0
def main():
    # generate private key
    private_key = Ed25519PrivateKey.generate()
    # generate auth key
    auth_key = AuthKey.from_public_key(private_key.public_key())

    # create intent identifier
    account_identifier = identifier.encode_account(
        utils.account_address_hex(auth_key.account_address()), None,
        identifier.TDM)
    encoded_intent_identifier = identifier.encode_intent(
        account_identifier, "XUS", 10000000)
    print(f"Encoded IntentIdentifier: {encoded_intent_identifier}")

    # deserialize IntentIdentifier
    intent_identifier = identifier.decode_intent(encoded_intent_identifier,
                                                 identifier.TDM)

    print(
        f"Account (HEX) from intent: {utils.account_address_hex(intent_identifier.account_address)}"
    )
    print(f"Amount from intent: {intent_identifier.amount}")
    print(f"Currency from intent: {intent_identifier.currency_code}")
コード例 #18
0
def _cover_buy(order: Order, quote: QuoteData) -> bool:
    deposit_address = get_inventory_deposit_address()
    trade_id = LpClient().trade_and_execute(
        quote_id=quote.quote_id,
        direction=Direction[order.direction],
        diem_deposit_address=deposit_address,
    )
    trade_info = _wait_for_trade(order=order, trade_id=trade_id)

    if not trade_info:
        update_order(
            order_id=OrderId(UUID(order.id)),
            cover_status=CoverStatus.FailedCoverLPTradeError,
        )
        return False

    update_order(
        order_id=OrderId(UUID(order.id)),
        cover_status=CoverStatus.PendingCoverValidation,
    )

    vasp_address, internal_subaddress = decode_account(
        deposit_address, context.get().config.diem_address_hrp()
    )
    if not _validate_blockchain_transaction(
        blockchain_version=trade_info.tx_version,
        vasp_address=utils.account_address_hex(vasp_address),
        internal_subaddress=internal_subaddress.hex(),
        amount=round(trade_info.amount),
    ):
        update_order(
            order_id=OrderId(UUID(order.id)),
            cover_status=CoverStatus.FailedCoverTransactionError,
        )
        return False

    return True
コード例 #19
0
    refill_amount_human = args.amount
    threshold_amount_human = args.threshold
    currencies = args.currencies
    network_chainid = args.network_chainid
    network_json_rpc_url = args.network_json_rpc_url
    sleep_interval = args.sleep_interval

if auth_key is None:
    print("Must get an authentication key to watch!")
    sys.exit(1)

diem_client = jsonrpc.Client(network_json_rpc_url)

watched_account_auth_key = AuthKey(bytes.fromhex(auth_key))
watched_account_addr = watched_account_auth_key.account_address()
watched_account_addr_hex = utils.account_address_hex(watched_account_addr)

refill_amount = int(refill_amount_human) * 1_000_000  # to microdiem
threshold_amount = int(threshold_amount_human) * 1_000_000  # to microdiem
sleep_interval = float(sleep_interval)

while True:
    print(f'current datetime: {datetime.now().isoformat().replace("T", " ")}')

    for currency in currencies:
        currency_balance = next(
            b.amount
            for b in diem_client.get_account(watched_account_addr).balances)
        print(f"{currency} balance is {currency_balance} ", )

        if currency_balance > threshold_amount:
コード例 #20
0
def main():
    print("#1 connect to testnet")
    client = testnet.create_client()

    print("#2 Generate Keys")
    # generate private key for sender account
    sender_private_key = Ed25519PrivateKey.generate()
    # generate auth key for sender account
    sender_auth_key = AuthKey.from_public_key(sender_private_key.public_key())
    print(
        f"Generated sender address: {utils.account_address_hex(sender_auth_key.account_address())}"
    )

    print("#3 Create account")
    faucet = testnet.Faucet(client)
    testnet.Faucet.mint(faucet, sender_auth_key.hex(), 100000000, CURRENCY)

    print("#4 Get account information")
    sender_account = client.get_account(sender_auth_key.account_address())

    events_key = sender_account.received_events_key
    print("#5 Start event listener")
    get_events_example.subscribe(client, events_key)

    print("#6 Add money to account")
    faucet = testnet.Faucet(client)
    testnet.Faucet.mint(faucet, sender_auth_key.hex(), 10000000, CURRENCY)

    print("#7 Generate Keys")
    # generate private key for receiver account
    receiver_private_key = Ed25519PrivateKey.generate()
    # generate auth key for receiver account
    receiver_auth_key = AuthKey.from_public_key(
        receiver_private_key.public_key())
    print(
        f"Generated receiver address: {utils.account_address_hex(receiver_auth_key.account_address())}"
    )

    print("#8 Create second account")
    faucet = testnet.Faucet(client)
    testnet.Faucet.mint(faucet, receiver_auth_key.hex(), 1000000, CURRENCY)

    print("#9 Generate IntentIdentifier")
    account_identifier = identifier.encode_account(
        utils.account_address_hex(receiver_auth_key.account_address()), None,
        identifier.TDM)
    encoded_intent_identifier = identifier.encode_intent(
        account_identifier, CURRENCY, 10000000)
    print(f"Encoded IntentIdentifier: {encoded_intent_identifier}")

    print("#10 Deserialize IntentIdentifier")
    intent_identifier = identifier.decode_intent(encoded_intent_identifier,
                                                 identifier.TDM)
    print(
        f"Account (HEX) from intent: {utils.account_address_hex(intent_identifier.account_address)}"
    )
    print(f"Amount from intent: {intent_identifier.amount}")
    print(f"Currency from intent: {intent_identifier.currency_code}")

    print("#11 Peer 2 peer transaction")
    # create script
    script = stdlib.encode_peer_to_peer_with_metadata_script(
        currency=utils.currency_code(intent_identifier.currency_code),
        payee=intent_identifier.account_address,
        amount=intent_identifier.amount,
        metadata=b'',  # no requirement for metadata and metadata signature
        metadata_signature=b'',
    )
    # create transaction
    raw_transaction = diem_types.RawTransaction(
        sender=sender_auth_key.account_address(),
        sequence_number=sender_account.sequence_number,
        payload=diem_types.TransactionPayload__Script(script),
        max_gas_amount=1_000_000,
        gas_unit_price=0,
        gas_currency_code=CURRENCY,
        expiration_timestamp_secs=int(time.time()) + 30,
        chain_id=testnet.CHAIN_ID,
    )
    # sign transaction
    signature = sender_private_key.sign(
        utils.raw_transaction_signing_msg(raw_transaction))
    public_key_bytes = utils.public_key_bytes(sender_private_key.public_key())

    signed_txn = utils.create_signed_transaction(raw_transaction,
                                                 public_key_bytes, signature)
    # submit transaction
    client.submit(signed_txn)
    # wait for transaction
    client.wait_for_transaction(signed_txn)
コード例 #21
0
 def __init__(self):
     super().__init__(utils.account_address_hex(DESIGNATED_DEALER_ADDRESS))