#!/usr/bin/env python3 # Copyright (c) 2022 The Bitcoin Unlimited developers import asyncio from test_framework.util import assert_equal from test_framework.electrumutil import ( ElectrumTestFramework, ) from test_framework.electrumconnection import ElectrumConnection from test_framework.environment import on_nex, on_bch class ElectrumTokenGenesisInfo(ElectrumTestFramework): async def run_test(self): # This test users nexad wallet to create and send tokens. # Mine and mature some coins. n = self.nodes[0] n.generate(120) cli = ElectrumConnection() await cli.connect() await self.sync_height(cli) try: await self.test_basic(n, cli) await self.test_with_token_history(n, cli) await self.test_decimal_places(n, cli) await self.test_genesis_minting_nft(n, cli) finally: cli.disconnect() async def test_basic(self, n, cli): addr = n.getnewaddress() if on_nex(): ticker = "TICKER" name = "Some Name" url = "https://example.org" doc_hash = ( "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" ) token_id = self.create_token( ticker, name, url, doc_hash, to_addr=addr, mint_amount=100 ) elif on_bch(): token_id = self.create_token(to_addr=addr, mint_amount=100) else: raise NotImplementedError() # Get token info from mempool NYI for NEX n.generate(1) await self.sync_height(cli) info = await cli.call("token.genesis.info", token_id) assert "height" in info if on_nex(): assert "txid" in info assert "txidem" in info assert_equal(token_id, info["group"]) assert "token_id_hex" in info assert_equal(doc_hash, info["document_hash"]) assert_equal(ticker, info["ticker"]) assert_equal(name, info["name"]) assert_equal(0, info["decimal_places"]) if on_bch(): assert "tx_hash" in info assert not "document_hash" in info assert not "ticker" in info assert not "name" in info assert_equal(None, info["bcmr"]) async def test_with_token_history(self, n, cli): """ Check that electrum is able to find genesis also when there are other token transactions within the same block as genesis transaction """ if on_bch(): # NYI - skip return addr = n.getnewaddress() token_id = self.create_token( "DUMMY", "dummy token", to_addr=addr, mint_amount=20 ) for _ in range(1, 20): n.token("send", token_id, addr, 10) n.generate(1) await self.sync_height(cli) info = await cli.call("token.genesis.info", token_id) assert_equal("DUMMY", info["ticker"]) # Test subgroup genesis not returning parent genesis nft_id = self.create_nft(token_id, n.getnewaddress(), 24) assert nft_id != token_id n.generate(1) await self.sync_all(cli) nft_info = await cli.call("token.genesis.info", nft_id) assert_equal(nft_id, nft_info["group"]) assert nft_info["ticker"] is None assert nft_info["token_id_hex"] != info["token_id_hex"] assert nft_info["height"] != info["height"] async def test_decimal_places(self, n, cli): if on_bch(): # Not supported - skip return ticker = "TICKER" name = "Some Name" url = "https://example.org" doc_hash = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" decimal_places = 11 addr = n.getnewaddress() token_id_with_decimals = self.create_token( ticker, name, url, doc_hash, decimal_places, to_addr=addr, mint_amount=20 ) token_id_no_decimal = self.create_token( ticker, name, url, doc_hash, to_addr=addr, mint_amount=20 ) n.generate(1) await self.sync_height(cli) info = await cli.call("token.genesis.info", token_id_with_decimals) assert_equal(11, info["decimal_places"]) info = await cli.call("token.genesis.info", token_id_no_decimal) assert_equal(0, info["decimal_places"]) async def test_genesis_minting_nft(self, n, cli): """ On BCH, a genesis transaction can mint NFT. Make sure it doesn't affect this API call. '""" if on_nex(): # Genesis does not mint NFT return token_id, txid = self.create_token( to_addr=n.getnewaddress(), mint_amount=42, bch_can_mint_nft=True, return_txid=True, ) await self.sync_mempool_count(cli) info = await cli.call("token.genesis.info", token_id) assert_equal(txid, info["tx_hash"]) if __name__ == "__main__": asyncio.run(ElectrumTokenGenesisInfo().main())